模糊查询与索引
参考 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 | 1 | TABLE 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 | 1 | TABLE 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 | 1 | TABLE 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 | 1 | TABLE 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 | 1 | INDEX FAST FULL SCAN| IDX_B$L_INTEREST_INFO_NAME | 141K| 1379K| 1915 (7)|
7 ----------------------------------------------------------------------------------------
但是对于使用%%这种查询且select获取的字段包含了模糊查询字段以外的,就很难用上索引了。