MySQL 什么情况下会索引失效?
在 MySQL 中建立索引来提高查询效率是人尽皆知的事情,但是并非所有的索引都会生效,根据不同的查询场景建立不同的索引是每个工程师必须掌握的技能。
什么情况下 MySQL 索引会失效?
在MySQL中,有些情况可能会导致索引失效,无法有效利用索引来加速查询。以下是一些常见的导致索引失效的情况:
不符合最左匹配原则
当查询条件不符合最左匹配原则时,索引可能会失效。例如:
SELECT * FROM users WHERE age = 30 AND name = 'Alice';
如果索引是 (name, age)
,则 age
作为查询条件在最左边列之前,因此不能有效利用该索引。
使用了不支持索引的操作符
一些操作符会导致索引失效,例如:
范围查询:当查询中包含了范围查询(如
BETWEEN
、<
、>
)但条件列未按索引顺序列出时,索引可能会失效。SELECT * FROM users WHERE salary > 50000 AND age = 30;
函数或表达式:在查询条件中对索引列使用函数或表达式会导致索引失效。例如:
SELECT * FROM users WHERE YEAR(date_of_birth) = 1990;
这里
YEAR(date_of_birth)
使用了函数,会导致索引失效。
数据类型不匹配
如果查询条件的数据类型与索引列的数据类型不匹配,会引发隐式的类型转换。例如:
SELECT * FROM users WHERE id = '123';
如果 id
是整数类型,将整数与字符串进行比较可能导致索引失效。
使用 LIKE
操作符的不匹配
前缀通配符:
LIKE
操作符中的前缀通配符(%
)会使索引失效。例如:SELECT * FROM users WHERE name LIKE '%Alice%';
在这种情况下,MySQL无法使用索引来优化查询。
前缀匹配:如果
LIKE
的模式以固定字符开始(不以%
开头),则可以利用索引。例如:SELECT * FROM users WHERE name LIKE 'Alice%';
不等于 <>
或 !=
操作符
在某些情况下,使用不等于操作符可能导致索引失效,尤其是在涉及范围查询时。例如:
SELECT * FROM users WHERE age <> 30;
JOIN 操作中的索引选择
在 JOIN
操作中,如果条件列没有被正确地索引,或者索引选择不当,也可能导致索引失效。例如:
SELECT * FROM orders
JOIN customers ON orders.customer_id = customers.id
WHERE customers.name = 'Alice';
如果 orders
表的 customer_id
列没有索引,可能导致查询效率下降。
ORDER BY
与 GROUP BY
的顺序不一致
如果 ORDER BY
或 GROUP BY
的顺序与索引顺序不一致,可能会导致索引失效。例如:
SELECT * FROM users ORDER BY age;
如果 age
列在索引中的位置不合适,可能会导致索引失效。