Mysql:索引失效的常见场景

索引失效的常见场景

不符合最佳左前缀原则

比如说现在创建一个联合索引:index_union(name,age),然后你的select语句是这样的

select * from user where age = 18

此情况下并不会触发index_union,因为where没使用上name

查询语句中存在函数,计算,数据类型转换

比如说现在创建两个普通索引:index_name(name)和index_age(age),然后你的select语句是这样的

select * from user where left(name,1) = '李'
select * from user where age + 1 = 80

此情况索引会失效

where使用了联合索引全部字段,但实际只用了一部分

比如说现在创建一个联合索引:index_union(name,age,sex),然后你的select语句是这样的

select * from user where name = 'zhangsan' and age > 50 and sex = 1

此select会用到index_union,但只用到name,age和sex不会用到,因为age是范围查询,优化器就不考虑使用age了

建议:尽量把一些频繁范围查询的字段,放在联合索引的靠后位置,比如说时间字段

!= 导致索引失效

比如说现在创建个普通索引:index_age(age),然后你的select语句是这样的:

select * from user where age != 8

此情况不会触发index_age

is null 触发索引,is not null不触发索引

比如说现在创建个普通索引:index_age(age),然后你的select语句是这样的:

select * from user where age is null //能触发索引
select * from user where age is not null //不能触发索引

建议:如果实际开发中真遇到查询 is not null 又要求查询得快,可以考虑将此字段设计成非空。比如说int类型,用0表示空,varchar用‘’表示空。这样就字段中全是有值的,不需要考虑is not null了

like以通配符%开头的

比如说现在创建个普通索引:index_name(name),然后你的select语句是这样的:

select * from user where name like '李%' //能触发索引
select * from user where name like '%李%' //触发不了索引

OR关联的where条件中存在未索引的字段

比如说现在创建个普通索引:index_name(name),然后你的select语句是这样的:

select * from user where name = 'zhangsan' OR age > 18

此情况不会触发index_name,因为优化器觉得name走索引后,age还要走全表,还不如都直接走全表。

posted @ 2023-01-16 11:02  爱编程DE文兄  阅读(58)  评论(0编辑  收藏  举报