删除索引后查询变慢本质是执行计划退化,优化器被迫将原本走索引的WHERE、JOIN、ORDER BY降级为全表扫描或文件排序,表现为EXPLAIN中type变为ALL、Extra出现Using filesort或temporary、rows_examined骤增,且UPDATE/DELETE可能因无索引升级为表锁引发雪崩。

删除索引后查询变慢,本质是执行计划退化
MySQL 不会因为索引被删就报错,而是默默把原本走索引的 WHERE、JOIN、ORDER BY 操作降级为全表扫描或文件排序。你看到的“变慢”,其实是优化器被迫选了更重的路径。
常见现象包括:
-
EXPLAIN中type从ref或range变成ALL -
Extra出现Using filesort或Using temporary - 慢查询日志里同一 SQL 的
rows_examined突然翻几十倍
UPDATE/DELETE 也依赖索引,删错会锁住整张表
很多人只盯着 SELECT,却忽略了写操作——InnoDB 的行锁是“靠索引定位”的。没有索引时,UPDATE t SET x=1 WHERE y=100 会升级为全表扫描+逐行加锁,锁等待迅速堆积。
这正是事故高发点:
- 低峰期看不出问题,流量一上来线程数暴涨
- CPU 和磁盘 IO 可能不高,但
SHOW PROCESSLIST里大量Waiting for table metadata lock或Updating - 连接池被占满,上游服务超时雪崩
主键、唯一索引、外键索引不能随便删
这类索引不只是加速查询,还承担约束职责:
-
DROP INDEX对主键无效,必须用ALTER TABLE ... DROP PRIMARY KEY,且会重建聚簇索引,代价极高 - 删掉唯一索引后,
INSERT不再校验重复,可能引发业务逻辑错误(比如注册邮箱重复) - 外键关联的索引,若未先
DROP FOREIGN KEY就删索引,语句会直接报错:ERROR 1553 (HY000): Cannot drop index 'xxx': needed in a foreign key constraint
怎么确认一个索引真没被用?别猜,查数据
别看字段名像“冷门”就动手。真正可靠的判断方式只有两种:
- 开
performance_schema后查sys.schema_unused_indexes(需 MySQL ≥ 5.7 且已加载 sys 库):SELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'your_db';
- 没开
performance_schema?至少跑 7 天慢查询日志 +pt-index-usage分析,重点关注WHERE、ON、GROUP BY里是否出现该索引字段
复合索引 (a,b,c) 即使只查 a = ? 也算被使用,不能因 b、c 没出现在条件里就认定冗余。


















