博物馆网站模版wordpress 系统要求
目录
一、快速定位索引失效的步骤
1. 使用 EXPLAIN 分析执行计划详解Mysql的Explain语句
2. 确认索引是否存在
3. 检查查询条件是否符合索引规则
二、常见索引失效场景及解决方法
1. 索引列参与计算或函数
2. 隐式类型转换
3. 使用 LIKE 以通配符开头
4. 使用 OR 连接非索引列
5. 索引选择性过低
6. 联合索引顺序错误
7. 使用 != 或 <> 操作符
8. IS NULL 或 IS NOT NULL 条件
9. 多个索引ORDER BY 顺序不一致
10. 全文索引的误用
三、高级排查工具
1. 开启慢查询日志
2. 使用 OPTIMIZER_TRACE 分析优化器决策
3. 强制使用索引测试
四、总结
一、快速定位索引失效的步骤
1. 使用 EXPLAIN
分析执行计划详解Mysql的Explain语句
EXPLAIN SELECT * FROM users WHERE age = 25 AND name = 'John';
重点关注以下字段:
-
type:若显示
ALL
(全表扫描)或index
(全索引扫描),可能索引未生效。 -
key:实际使用的索引名称,若为
NULL
表示未使用索引。 -
rows:预估扫描的行数,数值过大说明索引可能未生效。
-
Extra:若出现
Using filesort
或Using temporary
,可能索引未被用于排序或分组。
2. 确认索引是否存在
SHOW INDEX FROM users; -- 查看表的索引信息
确保查询涉及的列(尤其是 WHERE
、JOIN
、ORDER BY
中的列)已创建索引。
3. 检查查询条件是否符合索引规则
-
最左前缀原则:联合索引
(a, b, c)
必须按顺序使用,跳过中间列会导致后续列无法使用索引。WHERE a=1 AND c=3; -- 仅使用到 a 列的索引,c 列无法生效
-
范围查询阻断索引:范围查询(
>
、<
、BETWEEN
)后的列无法使用索引。WHERE a>10 AND b=20; -- 仅 a 列使用索引,b 列无法生效
二、常见索引失效场景及解决方法
1. 索引列参与计算或函数
-
失效示例:
SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 对索引列使用函数 SELECT * FROM users WHERE age + 10 > 30; -- 对索引列进行运算
-
优化方法:改写为直接使用索引列。
SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
2. 隐式类型转换
-
失效示例:
-- 假设 phone 是 VARCHAR 类型,但传入数字 SELECT * FROM users WHERE phone = 13800138000; -- 字符串转数字导致索引失效
-
优化方法:确保数据类型一致。
SELECT * FROM users WHERE phone = '13800138000';
3. 使用 LIKE
以通配符开头
-
失效示例:
SELECT * FROM users WHERE name LIKE '%John%'; -- 前导通配符导致索引失效
-
优化方法:尽量使用右通配符。
SELECT * FROM users WHERE name LIKE 'John%'; -- 可能使用索引
4. 使用 OR
连接非索引列
-
失效示例:
-- 假设 age 有索引,address 无索引 SELECT * FROM users WHERE age = 25 OR address = 'Beijing'; -- 全表扫描
-
优化方法:改用
UNION
拆分查询。SELECT * FROM users WHERE age = 25 UNION SELECT * FROM users WHERE address = 'Beijing';
5. 索引选择性过低
-
问题现象:索引列的值重复率过高(如性别字段),MySQL 可能放弃使用索引。
-
优化方法:删除低选择性索引,或结合其他列创建联合索引。
ALTER TABLE users ADD INDEX idx_gender_age (gender, age);
6. 联合索引顺序错误
-
问题现象:联合索引
(a, b, c)
,但查询未按最左前缀顺序使用,导致索引部分失效。 -
失效示例:
-- 索引 (a, b, c) SELECT * FROM table WHERE b = 2 AND a = 1; -- 正常使用索引(优化器自动调整顺序) SELECT * FROM table WHERE a = 1 AND c = 3; -- 仅用到 a 列索引,c 未生效 SELECT * FROM table WHERE b = 2; -- 索引完全失效(未使用最左列 a)
-
优化方法:
-
调整查询条件顺序,确保按最左前缀匹配。
-
根据高频查询场景,设计合理的联合索引顺序。
-
7. 使用 !=
或 <>
操作符
-
问题现象:非等值查询(如
!=
、NOT IN
)可能导致索引失效。 -
失效示例:
SELECT * FROM users WHERE age != 25; -- 可能全表扫描 SELECT * FROM orders WHERE status NOT IN (1, 2);
-
优化方法:
-
改写为等值查询或范围查询:
SELECT * FROM users WHERE age < 25 OR age > 25; -- 仍可能失效,需结合其他条件
-
若数据分布倾斜,强制使用索引(需测试验证):
SELECT * FROM users FORCE INDEX(idx_age) WHERE age != 25;
-
8. IS NULL
或 IS NOT NULL
条件
-
问题现象:索引列上使用
IS NULL
或IS NOT NULL
可能导致索引失效。 -
失效示例:
SELECT * FROM users WHERE phone IS NULL; -- 可能全表扫描
-
优化方法:若 NULL 值较少,添加条件冗余字段:
ALTER TABLE users ADD COLUMN is_phone_null TINYINT(1) DEFAULT 0; CREATE INDEX idx_phone_null ON users(is_phone_null); SELECT * FROM users WHERE is_phone_null = 1;
9. 多个索引ORDER BY
顺序不一致
-
问题现象:排序字段顺序与索引顺序不匹配,导致无法利用索引排序。
-
失效示例:
-- 索引 (a, b) SELECT * FROM table WHER ORDER BY a ASC, b DESC; -- 2个索引顺序不一致导致失效
-
优化方法:调整联合索引顺序,同升同降。
SELECT * FROM table WHER ORDER BY a ASC, b ASC; 同升同降
10. 全文索引的误用
-
问题现象:错误使用
LIKE
或MATCH AGAINST
导致索引失效。 -
失效示例:
-- 未使用全文索引 SELECT * FROM articles WHERE content LIKE '%database%';
-
优化方法:
-
对文本搜索需求改用全文索引(FULLTEXT Index)。
-
避免在全文索引列上混合使用
LIKE
和MATCH
。SELECT * FROM articles WHERE MATCH(content) AGAINST('database');
-
三、高级排查工具
1. 开启慢查询日志
-- 配置 my.cnf
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2 -- 记录执行超过2秒的SQL
通过慢日志定位高频低效 SQL。
2. 使用 OPTIMIZER_TRACE
分析优化器决策
SET optimizer_trace = 'enabled=on';
SELECT * FROM users WHERE age = 25; -- 执行你的查询
SELECT * FROM information_schema.optimizer_trace; -- 查看优化器选择索引的过程
3. 强制使用索引测试
SELECT * FROM users FORCE INDEX (idx_age) WHERE age = 25; -- 强制使用索引
对比强制索引前后的执行时间,判断优化器是否选错索引。
四、总结
-
核心原则:索引失效的本质是 无法快速定位数据范围。
-
关键检查点:
-
避免对索引列进行计算或函数操作。
-
确保查询条件符合最左前缀原则。
-
注意隐式类型转换和通配符使用。
-
-
工具辅助:
EXPLAIN
、慢查询日志、OPTIMIZER_TRACE
是排查利器。