使用sys.schema_unused_indexes排查废弃索引时需谨慎:该视图仅反映performance_schema采集周期内未被查询选中的索引,重启或采集时间过短易产生假阴性。需确认events_statements_history_long启用且数据非零,并保证业务高峰期持续采集至少24小时。还应交叉验证table_io_waits_summar
在MySQL索引优化实践中,sys.schema_unused_indexes视图常被用于识别废弃索引,但许多开发者对其存在误读。该视图反映的是performance_schema采集周期内未被查询选中的索引情况,而非绝对意义上的“从未被使用”。若MySQL刚重启或采集时间不足,COUNT_FETCH字段全为零,此时输出的结果多为假阴性,需谨慎对待。
在采取任何索引删除操作之前,务必完成以下三项前置确认:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
performance_schema.setup_consumers表中events_statements_history_long是否已启用。若该消费者关闭,sys.schema_unused_indexes将无数据可读取。SELECT COUNT(*) FROM events_statements_history_long,返回非零值才说明语句采集功能正常运作。
该视图的判定逻辑并非“索引建了没用就报出”,而是“在performance_schema已采集的查询中一次都未被选中”。MySQL刚重启或采集时间过短时,COUNT_FETCH全部归零,结果将呈现大量假阴性。
实际操作前务必执行以下检查:
SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE 'events_statements_%' AND ENABLED = 'NO' —— 若events_statements_history_long被关闭,sys.schema_unused_indexes将失去数据来源SELECT COUNT(*) FROM performance_schema.events_statements_history_long —— 非零值才表明语句采集已生效该视图仅告知索引“未被使用”,但无法区分是真闲置还是未进入采样窗口。更可靠的判断依据来自底层统计表:
SELECT OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, COUNT_FETCH, COUNT_READ FROM performance_schema.table_io_waits_summary_by_index_usage WHERE OBJECT_SCHEMA = 'your_db' AND INDEX_NAME = 'idx_xxx'
重点关注COUNT_FETCH和COUNT_READ是否均为零。若任一字段非零,说明索引确实被使用过;若均为零,需结合EXPLAIN和慢日志进一步判断是否存在漏采。
例如存在INDEX(a, b, c),但业务查询中仅出现WHERE a = AND c = ,优化器仍可能选择该索引(key字段显示索引名),但实际仅用到a列,c列因跳过b列而完全失效。
此时需通过EXPLAIN查看执行细节:
Using where但未出现Using index —— 表明未走覆盖扫描,大概率发生回表且部分列未参与过滤自动化脚本输出的“可删除列表”仅为起点,真正危险的是那些不显山露水的隐性依赖:
SELECT COUNT(*) FROM t WHERE ... 类聚合查询常走索引快速计数,但不会在table_io_waits_summary_by_index_usage中高频出现.exists()、Laravel的doesntExist()会生成SELECT 1 FROM t WHERE ...,这类语句轻量但关键,容易被忽略索引是否真正废弃,不取决于它是否出现在执行计划中,而取决于删除后是否会导致某条SQL从ref降级为ALL。这一判断无法全自动化,必须由人工盯住慢日志和核心路径的EXPLAIN结果来最终确认。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述