oracle like模糊查詢不能走索引?

這裏要糾正一個網上不少教程說的模糊匹配不能走索引的說法,由於在看《收穫,不止SQL優化》一書,裏面舉例說到了,而且本身也跟着例子實踐了一下,確實like一些特殊狀況也是能夠走索引的ide

例子來自《收穫,不止SQL優化》一書,實踐準備:測試

//建表,注意要非空數據
drop table t purge;
create table t as select * from dba_objects where object_id is not null;

select * from t;

//更新數據並建索引,用來測試
update t set object_id=rownum;

update t set object_name='AAALJB' where object_id=8;

update t set object_name='LJBAAA' where object_id=10;

create index idx_object_name on t(object_name);

用set autotrace on用來打印執行計劃,這裏注意了,用LJB%去模糊匹配,而後觀察執行計劃,發現是索引範圍掃描INDEX RANGE SCAN 的,由於去匹配LJB開頭的數據,索引是能夠範圍查詢並匹配到,因此是能走範圍索引掃描的,因此網上的說法是不全面的優化

SQL> set autotrace on
SQL> select object_id,object_name from t where object_name like 'LJB%';

 OBJECT_ID
----------
OBJECT_NAME
--------------------------------------------------------------------------------

        10
LJBAAA



執行計劃
----------------------------------------------------------
Plan hash value: 1138138579

--------------------------------------------------------------------------------

---------------

| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%C

PU)| Time     |

--------------------------------------------------------------------------------

---------------

|   0 | SELECT STATEMENT            |                 |     1 |    79 |     4
(0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T               |     1 |    79 |     4
(0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_NAME |     1 |       |     3
(0)| 00:00:01 |

--------------------------------------------------------------------------------

---------------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_NAME" LIKE 'LJB%')
       filter("OBJECT_NAME" LIKE 'LJB%')

Note
-----
   - dynamic sampling used for this statement (level=2)

SQL>

上面列舉了,能走索引的例子,而後改一下用%LJB去匹配,看看能不能走索引?this

SQL> set autotrace on
SQL> select object_id,object_name from t where object_name like '%LJB';

 OBJECT_ID
----------
OBJECT_NAME
--------------------------------------------------------------------------------

         8
AAALJB



執行計劃
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    12 |   948 |   288   (1)| 00:00:04 |
|*  1 |  TABLE ACCESS FULL| T    |    12 |   948 |   288   (1)| 00:00:04 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_NAME" IS NOT NULL AND "OBJECT_NAME" LIKE '%LJB')

Note
-----
   - dynamic sampling used for this statement (level=2)


統計信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1032  consistent gets
          0  physical reads
          0  redo size
        503  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

例子能夠看出是全表掃描的,不走索引,由於%LJB這種匹配,索引不能確認惟一性,一樣的%LJB%去匹配也是不走索引的code

相關文章
相關標籤/搜索