1. 不满足最左前缀法则
索引列的顺序很重要:
在联合索引中,查询条件必须从索引的最左边列开始,否则后续的索引列可能无法被利用。
例如,对于联合索引
(name, age, phone),查询条件必须包含name,否则无法利用索引。连续性原则:
查询条件中的索引列必须是连续的,不能跳过中间的列,否则后续的索引列将失效。
例如,查询条件为
name和phone,但跳过了age,那么phone这一列的索引将失效。全范围匹配原则:
如果查询条件中某个索引列使用了范围查询(如
>、<、BETWEEN),那么该列之后的索引列将失效。例如,查询条件为
name = 'Alice' AND age > 20,那么phone这一列的索引将失效,因为age是范围查询。
假设有一个联合索引
(name, age, phone),以下是一些查询条件的分析:
有效查询条件:
WHERE name = 'Alice' AND age = 25 AND phone = '123456'
分析:完全符合最左前缀法则,name、age和phone都能利用索引。
WHERE name = 'Alice' AND age = 25
分析:符合最左前缀法则,name和age都能利用索引。
WHERE name = 'Alice'
分析:符合最左前缀法则,name能利用索引。部分失效的查询条件:
WHERE name = 'Alice' AND phone = '123456'
分析:phone的索引失效,因为跳过了中间的age。只有name能利用索引。
WHERE age = 25 AND phone = '123456'
分析:name没有出现在查询条件中,整个联合索引失效,会走全表扫描。范围查询导致失效:
WHERE name = 'Alice' AND age > 20 AND phone = '123456'
分析:age是范围查询,phone的索引失效。只有name和age能利用索引。
2. 索引参与运算
1. 索引列被计算
当在查询条件中对索引列进行计算或使用函数时,MySQL 通常无法利用索引,因为索引是基于原始列值构建的,而计算后的值与索引结构不一致。
示例
假设有一个表
users,其中age列上有索引:sql复制
SELECT * FROM users WHERE age + 1 = 30;上述查询中,
age + 1是对索引列的计算,导致索引失效,MySQL 会进行全表扫描。
2. 隐式类型转换
当查询条件中的数据类型与索引列的数据类型不一致时,MySQL 会尝试进行隐式类型转换,这可能导致索引失效。
示例
假设
user_id列是INT类型,并且有索引:sql复制
SELECT * FROM users WHERE user_id = '123';上述查询中,
user_id是INT类型,但查询条件使用了字符串'123',MySQL 会尝试将字符串转换为数字,这可能导致索引失效。
3. 使用or和like不规范
在使用or的时候要求两个条件都必须是索引列,而使用like的时候只能后模糊匹配,否则都将走全表扫描
