如何在mysql中避免索引失效

来源:这里教程网 时间:2026-02-28 20:16:50 作者:

在MySQL中,索引是提升查询性能的关键手段,但不合理的SQL写法或表结构设计会导致索引无法被使用,从而大幅降低查询效率。要避免索引失效,核心在于理解索引的使用规则,并遵循最佳实践。

1. 避免在索引列上使用函数或表达式

如果对索引列进行计算、函数处理或类型转换,MySQL将无法直接使用索引。

错误示例:

SELECT * FROM users WHERE YEAR(create_time) = 2023;

即使

create_time
上有索引,
YEAR()
函数会让索引失效。

正确做法:

SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time 

这样可以利用

create_time
的范围扫描,走索引。

2. 遵循最左前缀原则(针对联合索引)

联合索引 (a, b, c) 要求查询条件从最左边开始连续使用,否则可能无法命中索引。

能用索引的情况: WHERE a = 1 WHERE a = 1 AND b = 2 WHERE a = 1 AND b = 2 AND c = 3

可能失效的情况:

WHERE b = 2(跳过 a) WHERE c = 3(只用 c) WHERE a = 1 AND c = 3(缺少 b,c 无法生效)

注意:如果查询只选择索引中的字段,即使顺序不全,也可能走覆盖索引。

3. 避免在 WHERE 条件中对索引列使用 !=、、NOT IN、NOT EXISTS

这些否定操作通常会导致全表扫描,因为索引更擅长查找“等于”或“范围”值。

建议替代方式: 用 IN 替代 NOT IN,配合允许为空的判断 拆分查询逻辑,用正向条件代替否定

例如:

WHERE status != 1
可能不走索引,可考虑是否能重构为
status IN (2,3)
等明确集合。

4. 尽量避免在索引列上使用 LIKE 以 % 开头

前导通配符会破坏索引的有序性。

索引失效:

WHERE name LIKE '%John%'
LIKE '%John'

可走索引:

WHERE name LIKE 'John%'

如果必须支持模糊搜索,可考虑全文索引(FULLTEXT)或引入搜索引擎如 Elasticsearch。

5. 注意隐式类型转换导致索引失效

当索引列是字符串类型,而查询时传入数字,MySQL会做隐式转换,导致索引失效。

示例:

SELECT * FROM users WHERE phone = 13812345678;
(phone 是 VARCHAR)

应改为:

SELECT * FROM users WHERE phone = '13812345678';

6. 合理使用 ORDER BY 和 GROUP BY

ORDER BY 和 GROUP BY 字段如果没有索引,或顺序与联合索引不一致,可能导致 filesort 或临时表。

建议: 为排序和分组字段建立合适索引 保持 ORDER BY 字段顺序与联合索引一致 避免混合 ASC 和 DESC(某些版本不支持索引优化)

7. 少用 OR 条件,尽量用 UNION

WHERE 中使用 OR 连接非同一索引字段时,可能无法走索引。

替代方案:

将 OR 查询拆分为 UNION ALL(如果无重复数据)或 UNION。

例如:

SELECT * FROM users WHERE a = 1 OR b = 2;
→ 改为:

SELECT * FROM users WHERE a = 1 UNION SELECT * FROM users WHERE b = 2;

基本上就这些常见场景。关键是在写SQL时时刻想着索引结构,结合 EXPLAIN 分析执行计划,及时发现潜在问题。索引有效与否,往往就在细节之间。

相关推荐