一.like查询与索引mysql
在oracle里的一个超级大的表中,咱们的where条件的列有建索引的话,会走索引惟一扫描INDEX UNIQUE SCAN。如select * from table where code = 'Cod25',而以下这些语句哪些会走索引呢?sql
经验证:
select * from table where code like 'Cod2%'会走索引,且走的是INDEX RANGE SCAN,而这样写like '%xxx'或'%xxx%'不会走索引,感受就像组合索引同样,直接用索引第一个字段会走索引,而用索引第二个字段则不会走索引。oracle
固然,若是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,这样查询效果很好,速度很快。spa
2)在mysql中,能够用locate和position函数,如table.field like '%AAA%'能够改成locate('AAA', table.field) > 0或POSITION('AAA' IN table.field)>0。.net
LOCATE(substr,str)、POSITION(substr IN str):返回子串 substr 在字符串 str 中第一次出现的位置。若是子串 substr 在 str 中不存在,返回值为 0。3d
3)在sql server中,能够给字段创建全文索引,用contains来检索数据,CONTAINS用法,能够参考:http://bijian1013.iteye.com/blog/2232872code
b.查询%xx的记录
在执行的时候,执行计划显示,消耗值,io值,cpu值均很是大,缘由是like后面前模糊查询致使索引失效,进行全表扫描。
解决方法:这种只有前模糊的sql能够改造以下写法
使用翻转函数+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.通常的索引:
当执行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX 时会用到索引。
2.函数索引:
当执行SELECT * FROM TABLE1 WHERE SUBSTR(COLUMN1,0,5) = XXX 时会用到索引。但执行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX时是不会用到索引的。通常状况下是最好不用建函数索引。
原文连接:https://blog.csdn.net/bolg_hero/article/details/77606734