【SQL優化】LIKE vs INDEX

secooler發表於2009-10-19
這裡給一個常識性的,SQL中like與索引使用的原則。很熟悉的朋友可以飄過鳥~~

1.包含一百萬行記錄的測試表
sec@ora10g> select count(*) from t;

  COUNT(*)
----------
   1000000

2.在x列上建立索引
sec@ora10g> create index i_t on t(x);

Index created.

3.直接查詢,可以利用到索引
sec@ora10g> set autot trace exp
sec@ora10g> select * from t where x = 'SEC';

Execution Plan
----------------------------------------------------------
Plan hash value: 2928007915

------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |  1214 |   101K|    51   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |  1214 |   101K|    51   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T  |  1214 |       |     5   (0)| 00:00:01 |
------------------------------------------------------------------------------------

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

   2 - access("X"='SEC')


4.以like 'SEC%'形式進行查詢,可以利用到索引
sec@ora10g> select * from t where x like 'SEC%';

Execution Plan
----------------------------------------------------------
Plan hash value: 2928007915

------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |  1214 |   101K|    51   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |  1214 |   101K|    51   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T  |  1214 |       |     5   (0)| 00:00:01 |
------------------------------------------------------------------------------------

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

   2 - access("X" LIKE 'SEC%')
       filter("X" LIKE 'SEC%')


5.以not like 'SEC%'形式進行查詢,無法利用到索引
sec@ora10g> select * from t where x not like 'SEC%';

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1000K|    82M|  2840   (2)| 00:00:35 |
|*  1 |  TABLE ACCESS FULL| T    |  1000K|    82M|  2840   (2)| 00:00:35 |
--------------------------------------------------------------------------

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

   1 - filter("X" NOT LIKE 'SEC%')

6.以like '%SEC'形式進行查詢,無法利用到索引
sec@ora10g> select * from t where x like '%SEC';

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 50103 |  4207K|  2826   (1)| 00:00:34 |
|*  1 |  TABLE ACCESS FULL| T    | 50103 |  4207K|  2826   (1)| 00:00:34 |
--------------------------------------------------------------------------

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

   1 - filter("X" LIKE '%SEC')


7.同樣道理,以like '%SEC%'形式進行查詢,同樣也無法利用到索引
sec@ora10g> select * from t where x like '%SEC%';

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 50103 |  4207K|  2826   (1)| 00:00:34 |
|*  1 |  TABLE ACCESS FULL| T    | 50103 |  4207K|  2826   (1)| 00:00:34 |
--------------------------------------------------------------------------

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

   1 - filter("X" LIKE '%SEC%')


8.小結
LIKE '%***'、LIKE '%***%'及NOT LIKE語句無法使用到索引;
儘量不使用LIKE語句,不可避免時,可使用like ' ***%'。

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-616907/,如需轉載,請註明出處,否則將追究法律責任。

相關文章