在沒有創建數據直方圖之前,查詢優化器是cbo,可能不會選擇代價最低(效率最高)的方式查詢.
先創建表
--日語假名表 CREATE TABLE JAPANESE_SOUNDMARK ( ID INTEGER PRIMARY KEY, ROMAJI VARCHAR2(10), PHONETIC_SYMBOL VARCHAR(20) );
創建序列
--創建自增長的序列,用於主鍵 CREATE SEQUENCE SEQ_JAPANESE_SOUNDMARK START WITH 1 NOMAXVALUE INCREMENT BY 1 NOCYCLE CACHE 10;
創建反向鍵索引
--給需要模糊查詢的列加上反向鍵索引 CREATE INDEX ROMAJI_REVERSE_INDEX ON JAPANESE_SOUNDMARK(ROMAJI) REVERSE;
創建普通索引
--普通索引 CREATE INDEX PHONETIC_SYMBOL_INDEX ON JAPANESE_SOUNDMARK(PHONETIC_SYMBOL);
注意:
以上語句均為DDL(Data Definition Language)語句,會自動提交事務,如果之前有DML(Data Manipulation Language)語句運行了,但沒提交事務,會將之前所有的DML語句也提交事務,ROLLBACK會失效.
1.沒有索引時(實際上不需要測試)
--模糊查詢,等值 EXPLAIN PLAN FOR SELECT * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE 'A'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
運行結果:
顯而易見:全表掃描
這個其實不需要測試,因為沒有索引只能走全表掃描,所以,like '%字符串'和like'字符串%'都是全表掃描.
2.不使用通配符,hint使用普通索引
--模糊查詢,等值 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK PHONETIC_SYMBOL_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE 'A'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Range Scan
3.使用通配符后綴,hint使用普通索引
--模糊查詢,以...開頭 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK PHONETIC_SYMBOL_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE 'A%'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
同樣是:
Index Range Scan
4.使用通配符前綴,hint使用普通索引
--模糊查詢,以...結尾 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK PHONETIC_SYMBOL_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE '%A'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Full Scan
5.不使用通配符,hint使用反向鍵索引
--模糊查詢,等值 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK ROMAJI_REVERSE_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE ROMAJI LIKE 'A'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Range Scan
6.使用通配符后綴,hint使用反向鍵索引
--模糊查詢,以...開頭 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK ROMAJI_REVERSE_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE ROMAJI LIKE 'A%'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)
結果:
Index Full Scan
7.使用通配符前綴,hint使用反向鍵索引
--模糊查詢,以...結尾 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK ROMAJI_REVERSE_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE ROMAJI LIKE '%A'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Full Scan
結論:
使用普通索引在使用通配符后綴時,只能走Index Range Scan,
而使用反向鍵索引在使用通配符后綴時,只能走Index Full Scan,
其他情況,兩種索引的索引使用方式相同.
一般來說,Index Range Scan效率要高於Index Full Scan,所以,使用普通索引來優化模糊查詢就行了.
全模糊查詢:
1.使用普通索引時
--全模糊查詢 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK PHONETIC_SYMBOL_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE '%A%'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Full Scan
但是,它有另外一種等價寫法:
--全模糊查詢 EXPLAIN PLAN FOR SELECT /*+ INDEX_RS(JAPANESE_SOUNDMARK PHONETIC_SYMBOL_INDEX) */ * FROM JAPANESE_SOUNDMARK WHERE PHONETIC_SYMBOL LIKE '%A' AND PHONETIC_SYMBOL LIKE 'A%'; --查看執行計划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
結果:
Index Range Scan