ITPub博客

首页 > 数据库 > Oracle > 【SQL优化】LIKE vs INDEX

【SQL优化】LIKE vs INDEX

原创 Oracle 作者:OCMU联盟 时间:2009-10-19 18:46:14 0 删除 编辑
这里给一个常识性的,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博客 ” ,链接:https://blog.itpub.net/70034820/viewspace-2994002/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
OCM联盟( Oracle Certified Master Union)是由侯圣文(ACE总监)发起的一个公益组织,旨在为每一个OCM大师提供一个可以继续展示自己才华,技术和实力的平台。

注册时间:2007-05-27

  • 博文量
    799
  • 访问量
    8407059