首页 >> 基础教程
2.
验证索引是否生效:
mysql索引哪些情况下会失效
MySQL索引失效通常由查询语句编写不当、索引设计缺陷或优化器决策导致。以下是主要失效场景及解决方案,附 EXPLAIN
诊断关键点:
一、查询语句问题(高频失效场景)
违反最左前缀原则(复合索引)
复合索引
(A,B,C)
,但查询未使用A
。CREATE INDEX idx_user ON users(name, age, city); SELECT * FROM users WHERE age = 30; -- 失效(未用name) SELECT * FROM users WHERE name = 'John'; -- 生效(使用最左列)
对索引列运算或函数处理
场景:索引列参与计算、函数调用或类型转换。
示例:
SELECT * FROM orders WHERE YEAR(create_time) = 2023; -- 失效 SELECT * FROM users WHERE CAST(phone AS CHAR) = '123'; -- 失效(隐式转换)
解决方案:
SELECT * FROM orders WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
模糊查询以
%
开头场景:
LIKE '%abc'
无法利用索引定位。示例:
SELECT * FROM products WHERE name LIKE '%Pro'; -- 全表扫描 SELECT * FROM products WHERE name LIKE 'Pro%'; -- 索引生效(最左匹配)
使用
OR
连接非索引字段场景:
OR
连接的字段中有任意一个无索引。示例:
SELECT * FROM users WHERE age = 25 OR address = 'Beijing'; --address无索引则全表扫描
解决方案:改用
UNION
:SELECT * FROM users WHERE age = 25 UNION SELECT * FROM users WHERE address = 'Beijing'; -- 确保address有索引
二、索引设计缺陷
1. 索引选择性过低
场景:索引列重复值过高(如性别、状态)。
诊断:
SHOW INDEX FROM users
查看Cardinality
(基数),值越低选择性越差。优化:避免为低选择性列单独建索引,可结合高频查询列建复合索引。
2. NULL
值过多
场景:索引列包含大量
NULL
时,IS NULL
可能无法使用索引。解决方案:建表时设置
NOT NULL DEFAULT
减少NULL
值。
三、优化器决策导致失效
全表扫描成本更低
场景:查询覆盖超过 15%~30% 数据时,优化器可能放弃索引。
诊断:
EXPLAIN
中type=ALL
且rows
值很大。优化:强制索引(谨慎使用):
SELECT * FROM users FORCE INDEX(idx_age) WHERE age > 10;
统计信息不准确
场景:表数据量剧烈变化后,优化器误判执行计划。
解决:定期更新统计信息:
ANALYZE TABLE users; -- 更新InnoDB统计信息
四、MySQL 特有陷阱
字符集/校对规则不匹配
场景:
JOIN
或WHERE
比较时字符集不一致。示例:
SELECT * FROM users u JOIN orders o ON u.name = o.customer_name -- 若字符集不同,索引失效
解决:统一字符集或使用
CONVERT()
转换。索引条件下推(ICP)失效
场景:MySQL 5.6+ 支持 ICP,但某些条件(如子查询)会使其失效。
诊断:
EXPLAIN
出现Using index condition
表示 ICP 生效,否则失效。
验证索引是否生效:EXPLAIN
关键字段
字段 | 理想值 | 失效标志 |
---|---|---|
type | ref 、range 、const | ALL (全表扫描) |
key | 显示索引名称 | NULL |
rows | 数值较小(扫描行数少) | 接近表总行数 |
Extra | Using index | Using filesort 、Using temporary |
高效索引使用原则
写查询:
避免索引列运算,
LIKE
右侧模糊。用
UNION
替代OR
,用IN
替代范围查询。建索引:
复合索引按 高频查询列 > 高选择性列 > 范围查询列 顺序排列。
避免对低选择性列单独建索引。
调优:
定期
ANALYZE TABLE
更新统计信息。监控慢查询日志:
slow_query_log = ON
。
通过
EXPLAIN SELECT ...
分析执行计划是定位索引问题的核心手段!
最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29