安全确认索引未被使用需三步:查performance_schema.table_io_waits_summary_by_index_usage中COUNT_STAR和COUNT_READ均为0;用EXPLAIN验证所有高频SQL的key字段;检查慢查询日志是否含该索引。
怎么安全确认一个索引是否真没被用过
MySQL 不会自动记录“谁查了哪个索引”,所以不能光看
或表结构就下结论。得结合实际查询路径和统计信息来交叉验证。
实操建议:
查
(MySQL 8.0+),重点关注
为 0 且
为 0 的索引;注意该视图默认可能关闭,需确认
已启用且相关消费者已打开
用
跑一遍业务中所有高频
、
、
语句,看
字段是否出现目标索引名;别漏掉带
、
、函数包裹列的查询,它们容易绕过预期索引
检查慢查询日志里有没有用到该索引的语句(搜索
或
配合索引名)
DROP INDEX 时为什么有时卡住或报错
不是语法写错,而是 MySQL 在删索引前要做元数据锁(MDL)和表级操作校验,尤其在高并发写入场景下容易暴露问题。
常见错误现象:
:索引名拼错,或大小写不匹配(Linux 下表名/索引名区分大小写)
命令长时间无响应:其他事务正持有该表的
锁(比如长事务、未提交的
),
必须等它释放
:发生在 MyISAM 表上,或 MySQL 5.7 以下版本对主键索引的误操作(主键不能用
删除)
稳妥做法是先执行
看锁状态,再决定是否杀掉阻塞事务。
删除索引后性能反而变差?这些隐性依赖要提前扫
索引不只是加速
,还影响排序(
)、分组(
)、覆盖扫描(
),甚至外键约束和唯一性保障。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
容易踩的坑:
以为只用在
条件里的索引可以删,结果发现某个
查询没了索引后从
变成全表扫描
唯一索引(
)被删,导致应用层重复插入不报错,数据一致性被破坏
外键字段没索引(MySQL 要求外键列必须有索引),删掉后后续
/
外键关联行会变慢,甚至报错
联合索引删掉前缀列索引(如已有
,又建了单独的
),删后者看似冗余,但某些
场景下优化器可能更倾向用单列索引做排序
批量清理索引时如何控制风险
别一次性删多个,尤其在线上核心表。MySQL 删索引本质是重建表(除
支持的极简变更外),耗时和锁表现差异很大。
关键判断点:
用
确认存储引擎:InnoDB 支持
(5.6+),但删二级索引仍是轻量级操作;MyISAM 必须复制整个 .MYI 文件,锁表时间长
MySQL 8.0+ 对非主键二级索引支持
,命令形如
,几乎不锁表;但前提是没用到全文索引、空间索引等不支持类型
大表删索引前,先在从库或影子库上跑一遍,观察
耗时和
是否飙升
删完立刻查
确认索引消失,再用
验证关键语句执行计划没退化
真正麻烦的从来不是“删不删”,而是“删完谁在用、谁不知道自己在用”。线上删索引前,最好把最近一周的
和应用层 SQL 日志拉出来 grep 一遍索引名——人眼比文档更可靠。
SHOW INDEXperformance_schema.table_io_waits_summary_by_index_usageCOUNT_STARCOUNT_READperformance_schemaEXPLAINSELECTUPDATEDELETEkeyORINkey: index_nameExtra: Using indexERROR 1091 (42000): Can't DROP 'idx_name'; check that column/key existsMDL_SHARED_WRITEUPDATEDROP INDEXERROR 1025 (HY000): Error on rename...DROP INDEXSELECT * FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA = 'db_name' AND OBJECT_NAME = 'tbl_name';WHEREORDER BYGROUP BYUsing indexWHEREORDER BY created_at LIMIT 10filesortUNIQUE KEYINSERTUPDATEERROR 150(a,b,c)(a)WHERE a = ? ORDER BY bALGORITHM=INSTANTSHOW CREATE TABLE tbl_nameALGORITHM=INPLACEALGORITHM=INSTANTALTER TABLE t DROP INDEX idx_name, ALGORITHM=INSTANT;ALTERinnodb_buffer_pool_wait_freeinformation_schema.STATISTICSEXPLAINslow_log