MySQL索引失效会导致查询性能下降,常见原因及解决方案如下:
一、使用OR条件
-
原因:当OR条件中有一个列没有索引时,索引可能失效
-
解决方法:确保OR条件中的所有列都有索引,或使用UNION替代OR
-- 不推荐 SELECT * FROM table WHERE col1 = 'value' OR col2 = 'value'; -- 推荐 SELECT * FROM table WHERE col1 = 'value' UNION SELECT * FROM table WHERE col2 = 'value';
(注:UNION 操作符返回两个查询的结果集的并集,去除重复记录。)
二、使用LIKE以通配符开头
-
原因:LIKE'%value'或LIKE'%value%'会导致索引失效
-
解决方案:尽量避免以通配符开头,或使用全文索引
-- 不推荐 SELECT * FROM table WHERE col LIKE '%value'; -- 推荐 SELECT * FROM table WHERE col LIKE 'value%';
三、对索引列使用函数或表达式
-
原因:对索引列使用函数表达式(如WHERE YEAR(col)=2023)会导致索引失效
-
解决方案:避免在索引列上使用函数或表达式
-- 不推荐 SELECT * FROM table WHERE YEAR(col) = 2023; -- 推荐 SELECT * FROM table WHERE col >= '2023-01-01' AND col < '2024-01-01';
四、数据类型不匹配
-
原因:查询条件与列数据类型不匹配(如字符串列与数字比较)会导致索引无效
-
解决方案:确保查询条件与列数据类型一致
-- 不推荐 SELECT * FROM table WHERE col = 123; -- col 是字符串类型 -- 推荐 SELECT * FROM table WHERE col = '123';
五、使用NOT或!=
-
原因:NOT或!=可能导致索引失效
-
解决方案:尽量避免使用NOT或!=,或考虑其他查询方式
-- 不推荐 SELECT * FROM table WHERE col != 'value'; -- 推荐 SELECT * FROM table WHERE col = 'value1' OR col = 'value2';
六、复合索引未遵循最左前缀原则
-
原因:复合索引未按最左前缀原则使用时,索引可能失效
-
解决方案:确保查询条件从符合索引的最左列开始
-- 复合索引 (col1, col2) -- 不推荐 SELECT * FROM table WHERE col2 = 'value'; -- 推荐 SELECT * FROM table WHERE col1 = 'value' AND col2 = 'value';
七、数据分布不均
-
原因:当某列数据分布不均时,MySQL可能选择全表扫描而非索引
-
解决方案:使用FORCE INDEX强制使用索引,或优化查询
-- 强制使用索引 SELECT * FROM table FORCE INDEX (index_name) WHERE col = 'value';
八、索引选择性低
-
原因:索引选择性低(如布尔列)时,MySQL可能不使用索引
-
解决方案:考虑删除低选择性的索引,或结合其他列创建复合索引
-- 低选择性索引 CREATE INDEX idx ON table (low_selectivity_col); -- 高选择性复合索引 CREATE INDEX idx ON table (low_selectivity_col, high_selectivity_col);
九、查询返回大量数据
-
原因:当查询返回大量数据时,MySQL可能选择全表扫描
-
解决方案:优化查询条件,减少返回数据量,或使用分页
-- 不推荐 SELECT * FROM table WHERE col > 'value'; -- 推荐 SELECT * FROM table WHERE col > 'value' LIMIT 100;
十、索引损坏
-
原因:索引损坏会导致索引失效
-
解决方案:使用REPAIR TABLE或OPTIMIZE TABLE修复索引
REPAIR TABLE table_name; OPTIMIZE TABLE table_name;
总结
索引失效的原因多样,常见问题包括 OR
条件、LIKE
通配符、函数使用、数据类型不匹配等。通过优化查询、调整索引设计,可以有效避免索引失效,提升查询性能。