模糊查询与索引

参考 http://tech.ccidnet.com/art/3089/20080405/1410979_1.html。

通配符(%)在搜寻词首出现,一般会导致Oracle系统不使用索引。因此,要尽量避免在模糊查询中使用通配符开头,或者是开头结尾都有通配符,这样会导致降低查询速度。

--创建一个name字段的索引

create index IDX_B$L_INTEREST_INFO_NAME on B$L_INTEREST_INFO (NAME);

    以下语句不能使用name字段索引:

select * from b$l_interest_info where name like '%瑞德工业园%';

2 ----------------------------------------------------------------------------

3 | Id | Operation         | Name              | Rows | Bytes | Cost (%CPU)|

4 ----------------------------------------------------------------------------

5 |   0 | SELECT STATEMENT |                   |   141K| 8139K| 5426   (4)|

6 |   1TABLE ACCESS FULL| B$L_INTEREST_INFO |   141K| 8139K| 5426   (4)|

7      ----------------------------------------------------------------------------

如果遇到模糊查询的例子,尽量将通配符放在末尾,以常量开头,那么可以使用上索引,如下语句所示:

select * from b$l_interest_info where name like '瑞德工业园%';

2       -----------------------------------------------------------------------------------------------

3       | Id | Operation                   | Name                       | Rows | Bytes | Cost (%CPU)|

4       -----------------------------------------------------------------------------------------------

5       |   0 | SELECT STATEMENT            |                            | 1278 | 75402 |   360   (1)|

6       |   1TABLE ACCESS BY INDEX ROWID| B$L_INTEREST_INFO          | 1278 | 75402 |   360   (1)|

7       |   2 |   INDEX RANGE SCAN          | IDX_B$L_INTEREST_INFO_NAME | 1278 |       |     6   (0)|

8       -----------------------------------------------------------------------------------------------

 

如果必须将通配符放在开头,以常量结束,那么可以创建一个反向键索引

--在name字段创建一个反向键索引

create index idx_interest_info_name_re on b$l_interest_info(reverse(name));

analyze table b$l_interest_info compute statistics for table for all indexes;

--没有用到反向键索引

select * from b$l_interest_info where name like '%瑞德工业园';

2      ----------------------------------------------------------------------------

3      | Id | Operation         | Name              | Rows | Bytes | Cost (%CPU)|

4      ----------------------------------------------------------------------------

5      |   0 | SELECT STATEMENT |                   |   141K| 8139K| 5426  (4)|

6      |   1TABLE ACCESS FULL| B$L_INTEREST_INFO |   141K| 8139K| 5426   (4)|

7      ----------------------------------------------------------------------------

 

因此,要使用反向键索引还必须加上reverse关键字

--用上了反向键索引IDX_INTEREST_INFO_NAME_RE

select * from b$l_interest_info where reverse(name) like reverse('%瑞德工业园');

2       ----------------------------------------------------------------------------------------------

3       | Id | Operation                   | Name                      | Rows | Bytes | Cost (%CPU)|

4       ----------------------------------------------------------------------------------------------

5       |   0 | SELECT STATEMENT            |                           |   141K| 8139K| 5233   (1)|

6       |   1TABLE ACCESS BY INDEX ROWID| B$L_INTEREST_INFO         |   141K|  8139K| 5233   (1)|

7       |   2 |   INDEX RANGE SCAN          | IDX_INTEREST_INFO_NAME_RE | 25429 |       |    77   (2)|

8       ----------------------------------------------------------------------------------------------

 

如果开头结尾都要用到通配符,且select获取的字段只有该模糊查询字段,则可以用上索引:

--用到了name字段的一般索引IDX_B$L_INTEREST_INFO_NAME

select name from b$l_interest_info where name like '%瑞德工业园%';

2       ----------------------------------------------------------------------------------------

3       | Id | Operation            | Name                       | Rows | Bytes | Cost (%CPU)|

4       ----------------------------------------------------------------------------------------

5       |   0 | SELECT STATEMENT     |                            |   141K| 1379K| 1915   (7)|

6       |   1INDEX FAST FULL SCAN| IDX_B$L_INTEREST_INFO_NAME |   141K| 1379K| 1915   (7)|

7       ----------------------------------------------------------------------------------------

但是对于使用%%这种查询且select获取的字段包含了模糊查询字段以外的,就很难用上索引了。
posted on 2011-06-15 14:11  蓝紫  阅读(14548)  评论(0编辑  收藏  举报