模糊查詢是海量資料檢索的核心需求。本文系統整理 LIKE 通配符用法、INSTR 函數替代方案,並深入分析全表掃描瓶頸與索引優化路徑。
| 通配符 | 意義 | 範例 | 匹配結果 |
|---|---|---|---|
% | 零或多個字元 | LIKE '%三%' | 包含「三」:張三、小三、三腳貓、貓三腳 |
LIKE '三%' | 以「三」開頭:三腳貓 | ||
LIKE '%三' | 以「三」結尾:張三、小三 | ||
_ | 單一任意字元(限制長度) | LIKE '_三_' | 三字元且中間為「三」:貓三腳 |
LIKE '三__' | 三字元且首字為「三」:三腳貓 | ||
[...] | 字元集合中任一字元(類正則) | LIKE '[張李王]三' | 張三、李三、王三 |
| 範圍簡寫 | LIKE '老[1-9]' | 老1~老9 | |
[^...] | 排除字元集合 | LIKE '[^張李]三' | 非張/李開頭的「三」結尾 |
多關鍵字 AND 條件: 需同時包含「三」與「貓」時,用LIKE '%三%' AND LIKE '%貓%';LIKE '%三%貓%'只能匹配「三...貓」順序,會漏掉「貓...三」。
INSTR(欄位, '關鍵字') > 0 -- 等同 LIKE '%關鍵字%' INSTR(欄位, '關鍵字') = 1 -- 等同 LIKE '關鍵字%' INSTR(欄位, '關鍵字') = 0 -- 等同 NOT LIKE '%關鍵字%'
實測 INSTR 比 LIKE 效率高不少,但同屬逐行掃描,大數據量下仍受限於全表掃描。
SELECT id, name FROM user
WHERE INSTR('101914,104703', id) > 0;
-- 等價於 id IN (101914, 104703),適合動態 ID 清單場景
根因: Oracle 無法利用 B-Tree 索引進行 %關鍵字% 或 INSTR 搜尋,只能採用 全表順序掃描。複雜查詢或大表下,回應時間明顯下降。
LIKE '關鍵字%') 可使用 B-Tree 索引範圍掃描。CTXSYS.CONTEXT 索引,支援語幹分析、模糊匹配、評分排序。CREATE INDEX idx_upper_name ON emp(UPPER(ename)) 配合 WHERE UPPER(ename) LIKE 'SMITH%'。索引合理應用仍在研究中... 核心原則:避免前導萬用字元、善用功能性索引、大量全文搜尋上 Oracle Text 或專用引擎。