MySQL 索引失效是数据库性能优化中常见的问题,理解索引失效的场景对于提升查询效率至关重要。以下是 MySQL 索引失效的常见场景及解决方案:
场景:复合索引(a, b, c)在以下查询中失效:
-- 未从索引首列开始
SELECT * FROM table WHERE b = 1 AND c = 2;
-- 跳过中间列
SELECT * FROM table WHERE a = 1 AND c = 2;解决方案:
-- 使用函数
SELECT * FROM table WHERE YEAR(create_time) = 2023;
-- 使用表达式
SELECT * FROM table WHERE price * 1.1 > 100;解决方案:
将计算移到查询条件右侧:sql
SELECT * FROM table WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01'; SELECT * FROM table WHERE price > 100 / 1.1;
-- 字段类型为VARCHAR,但查询时未加引号
SELECT * FROM table WHERE phone = 13800138000;
-- 字段类型为INT,但查询时加了引号
SELECT * FROM table WHERE id = '123';解决方案:
EXPLAIN检查是否存在类型转换SELECT * FROM table WHERE name LIKE '%keyword';解决方案:
避免通配符开头,改用:sql
SELECT * FROM table WHERE name LIKE 'keyword%';SELECT * FROM table WHERE a = 1 OR b = 2;解决方案:
若a和b均有独立索引,可拆分为UNION:sql
SELECT * FROM table WHERE a = 1 UNION SELECT * FROM table WHERE b = 2;(a, b)创建复合索引SELECT * FROM table WHERE column IS NULL;
SELECT * FROM table WHERE column IS NOT NULL;解决方案:
NOT NULL约束对IS NULL条件创建索引:sql
CREATE INDEX idx_column ON table (column);场景:复合索引(a, b, c)在以下查询中b和c索引失效:
SELECT * FROM table WHERE a > 1 AND b = 2 AND c = 3;解决方案:
将等值条件前置:sql
SELECT * FROM table WHERE b = 2 AND a > 1 AND c = 3;(b, a, c)创建复合索引场景:
解决方案:
ANALYZE TABLE更新统计信息使用FORCE INDEX强制使用索引:sql
SELECT * FROM table FORCE INDEX (idx_column) WHERE column = 'value';-- 复合索引 (a, b)
SELECT a, b FROM table WHERE a = 1; -- 覆盖索引有效
SELECT a, b, c FROM table WHERE a = 1; -- 覆盖索引失效解决方案:
c:(a, b, c)场景:
解决方案:
启用索引:sql
ALTER TABLE table ENABLE KEYS;重建索引:sql
ALTER TABLE table DROP INDEX idx_column; ALTER TABLE table ADD INDEX idx_column (column);场景:
WHERE子句中对主键和唯一索引使用范围查询时会失效解决方案:
使用 EXPLAIN 分析查询:
EXPLAIN SELECT * FROM table WHERE column = 'value';(a, b)包含了索引(a)定期维护索引:
ANALYZE TABLE table; -- 更新统计信息 OPTIMIZE TABLE table; -- 重建表和索引监控索引使用情况:
SHOW STATUS LIKE 'Handler_read%';通过避免上述场景,合理设计索引,并结合EXPLAIN工具进行分析,可显著提升 MySQL 查询性能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。