like查询如何有索引效果

一.like查询与索引

        在oracle里的一个超级大的表中,我们的where条件的列有建索引的话,会走索引唯一扫描INDEX UNIQUE SCAN。如select * from table where code = 'Cod25',而如下这些语句哪些会走索引呢?

Sql代码   收藏代码
  1. select * from table where code like 'Code2%'  
  2. select * from table where code like '%ode2%'  
  3. select * from table where code like '%ode2'  

经验证:
        select * from table where code like 'Cod2%'会走索引,且走的是INDEX RANGE SCAN,而这样写like '%xxx'或'%xxx%'不会走索引,感觉就像组合索引一样,直接用索引第一个字段会走索引,而用索引第二个字段则不会走索引。

        当然,如果select * from table where code like 'Cod%' 查询的结果就是所有记录,走索引和full table scaN的结果是一样的,所以也将是全表扫描。可以换成select * from table where code like 'Code2%'或者 select count(*) from table where code like 'Cod%'试试,应该不会是全表扫描。

 

二.优化like查询

1.经上面测试,like查询结果如下:
        a.like %keyword    索引失效,使用全表扫描。但可以通过翻转函数+like前模糊查询+建立翻转函数索引=走翻转函数索引,不走全表扫描。如where reverse(code) like reverse('%Code2')
        b.like keyword%    索引有效。  
        c.like %keyword%   索引失效,也无法使用反向索引。
2.优化like查询:
        a.使用其它函数来进行模糊查询,如果出现的位置大于0,表示包含该字符串,查询效率比like要高。

        1)在oracle中,可以用instr,这样查询效果很好,速度很快。

Sql代码   收藏代码
  1. select count(*) from table t where instr(t.code,'Cod2%') > 0  
        2)在mysql中,可以用locate和position函数,如table.field like '%AAA%'可以改为locate('AAA', table.field) > 0或POSITION('AAA' IN table.field)>0。

        LOCATE(substr,str)、POSITION(substr IN str):返回子串 substr 在字符串 str 中第一次出现的位置。如果子串 substr 在 str 中不存在,返回值为 0。

        3)在sql server中,可以给字段建立全文索引,用contains来检索数据,CONTAINS用法,可以参考:http://bijian1013.iteye.com/blog/2232872

        b.查询%xx的记录  

Sql代码   收藏代码
  1. select count(c.c_ply_no) as COUNT  
  2.   from Policy_Data_All c, Item_Data_All i  
  3.  where c.c_ply_no = i.c_ply_no  
  4.    and i.C_LCN_NO like ’%245′  
        在执行的时候,执行计划显示,消耗值,io值,cpu值均非常大,原因是like后面前模糊查询导致索引失效,进行全表扫描。
        解决方法:这种只有前模糊的sql可以改造如下写法
Sql代码   收藏代码
  1. select count(c.c_ply_no) as COUNT  
  2.   from Policy_Data_All c, Item_Data_All i  
  3.  where c.c_ply_no = i.c_ply_no  
  4.    and reverse(i.C_LCN_NO) like reverse('%245')  
        使用翻转函数+like前模糊查询+建立翻转函数索引=走翻转函数索引,不走全扫描。有效降低消耗值,io值,cpu值这三个指标,尤其是io值的降低。

        建函数索引:create index p_idx on table(instr(code,'Code2'));需进一步说明的是,这样的话,只有where instr(code,'Code2')才会走INDEX RANGE SCAN,其它如where instr(code, 'Code3')会走INDEX FAST FULL SCAN甚至TABLE ACCESS FULL。

        另外,select * from table where upper(code) = 'abcD',会走TABLE ACCESS FULL。如果建函数索引create index idx_upper on table(upper(code));之后,将会是INDEX RANGE SCAN,如下所示:

 

PS:一般索引和函数索引的区别

1.一般的索引:

Sql代码   收藏代码
  1. create index P_IDX ON TABLE1(COLUMN1);  

        当执行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX 时会用到索引。

2.函数索引:

Sql代码   收藏代码
  1. CREATE INDEX P_IDX ON TABLE1(SUBSTR(COLUMN1,0,5));  

        当执行SELECT * FROM TABLE1 WHERE SUBSTR(COLUMN1,0,5) = XXX 时会用到索引。但执行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX时是不会用到索引的。一般情况下是最好不用建函数索引。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当 SQL 中使用 LIKE 操作符进行模糊匹配时,如果没有正确使用索引,可能会导致索引失效,从而影响查询性能。以下是一些可能导致 LIKE 索引失效的情况: 1. 前导通配符:如果 LIKE 表达式以通配符 '%' 开头,索引将无法有效利用。例如,"WHERE column LIKE '%abc'",这种情况下索引将无法生效。 2. 不适当的通配符位置:如果 LIKE 表达式中的通配符位于开头和结尾之间,而不是结尾之后,索引效果可能会减弱。例如,"WHERE column LIKE 'abc%def'",索引可能无法完全匹配。 3. 多个通配符:如果 LIKE 表达式中包含多个通配符,如 '%' 或 '_',索引可能无法生效。例如,"WHERE column LIKE '%abc%def%'",这种情况下索引可能无法使用。 4. 字符集问题:如果列的字符集与 LIKE 表达式中的字符集不匹配,索引可能无法使用。确保字符集一致可以提高索引效果。 5. 数据类型问题:如果列的数据类型与 LIKE 表达式中的数据类型不匹配,索引可能无法使用。确保数据类型一致可以提高索引效果。 为了让 LIKE 操作符在查询中有效利用索引,可以考虑以下方法: - 尽量避免在 LIKE 表达式的开头使用通配符。 - 使用索引友好的通配符位置,将通配符放在结尾之后。 - 避免使用多个通配符。 - 确保字符集和数据类型一致。 如果以上方法无法解决问题,可以考虑其他技术手段,如全文搜索引擎或者使用其他类型的索引(如全文索引),以满足模糊查询的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值