不能直接当索引建议用,它仅标识从未被查询使用的索引,不考虑update/delete依赖、约束功能及查询模式变化,且依赖performance schema开启状态。

MySQL 8.0+ 自带的 sys.schema_unused_indexes 能不能当索引建议用?
不能直接当优化建议用,它只告诉你“哪些索引从没被查询用过”,不回答“该建什么索引”。误删它标出的索引可能让慢查询更慢——比如某个索引虽未被 SELECT 使用,但正被 UPDATE 或 DELETE 的 WHERE 条件依赖着。
常见错误现象:DROP INDEX 后写操作变卡、唯一约束失效、外键关联异常。
- 它依赖 Performance Schema 的采集开关,
performance_schema必须为ON,且相关消费者(如events_statements_history_long)需启用 - 只统计开启采集后的历史,重启 MySQL 或清空历史表就归零
- 完全不考虑查询模式变化:昨天不用的索引,今天加了新报表就可能成关键路径
EXPLAIN FORMAT=TREE 和 EXPLAIN ANALYZE 哪个更适合定位缺失索引?
EXPLAIN ANALYZE 更直接。它真跑一遍语句,把实际执行路径、每层耗时、行数偏差全打出来,比纯预估的 FORMAT=TREE 更容易揪出“本该走索引却走了全表扫描”的场景。
使用场景:线上刚出现的慢查询,想快速判断是否缺索引或索引失效。
-
EXPLAIN ANALYZE会真实执行语句(含修改类),生产环境慎用;只对SELECT安全 - 关注输出里的
rows_examined和rows_read差距——如果前者远大于后者,大概率有索引没生效 -
possible_keys为空但key也为NULL,基本确认当前条件无可用索引
mysql\_server_audit 插件和 slow_query_log 怎么配合抓高频低效查询?
单靠慢日志漏得太多:long_query_time=1 会放过大量执行 0.8 秒但调用几千次的查询;审计插件能记录所有语句,但默认不统计耗时。必须组合用。
实操要点:
- 开
slow_query_log+log_queries_not_using_indexes = ON,强制捕获无索引扫描的语句 - 审计插件开启
audit_log_include_accounts过滤业务账号,避免 DBA 操作刷屏 - 用
pt-query-digest合并分析两者输出,重点看Rows_examined高 +Rows_sent低的查询(典型索引覆盖不足)
为什么 pt-online-schema-change 不适合边建索引边压测?
它建索引是在影子表上,但 DML 同步过程会锁原表的 metadata_lock,高并发写入下容易堆积,反而拖垮线上服务。真正的“在线”建索引,MySQL 5.6+ 应该用 ALGORITHM=INPLACE,而不是工具模拟。
容易踩的坑:
-
pt-osc默认在拷贝数据阶段建索引,此时主表仍可写,但同步延迟会导致主从不一致风险升高 - 若原表有
FULLTEXT或SPATIAL索引,pt-osc会退化为COPY模式,锁表时间不可控 - 建完索引立刻切表,但应用缓存的执行计划还没更新,可能继续走旧路径,需要手动
FLUSH TABLES或等query_cache过期
复杂点在于:索引是否有效,不只看能不能建成功,更要看查询是否真正命中、是否引发锁竞争、是否让缓冲池压力陡增——这些都得在业务流量下观察 Innodb_row_lock_waits 和 Key_reads 这类指标。











