mysql中删除索引与性能优化

3次阅读

删除索引前必须确认其实际使用情况,否则可能导致查询变慢;需通过 performance_schema 或 sys 库视图验证,不可仅凭字段名判断,并注意主键、唯一索引及外键索引的特殊性。

mysql 中删除索引与性能优化

删除索引前必须确认它是否被查询实际使用

很多团队一看到“某个索引没被创建时的字段”就直接删,结果线上 SELECT 变慢、EXPLAIN 显示全表扫描。MySQL 不会主动告诉你哪个索引正在被用——得自己查。最可靠的方式是开启 performance_schema 中的 table_io_waits_summary_by_index_usage 表(MySQL 5.6+),或用 sys.schema_unused_indexes 视图(需启用 performance_schema 并加载 sys 库)。

注意:INFORMATION_SCHEMA.STATISTICSSHOW INDEXES 只告诉你“有”,不告诉你“用没用”。临时禁用索引(ALTER TABLE …… DISABLE KEYS)在 InnoDB 中无效,别试。

  • 检查是否真没用:
    SELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'your_db';
  • 若没开 performance_schema,至少跑一周慢查询日志 + pt-index-usage 工具 分析
  • 复合索引中部分字段被查询用到(比如 (a,b,c) 上只查 a = ?),该索引仍算“被使用”,不能仅因 c 没出现就删

DROP INDEX 语句本身会锁表(InnoDB 下取决于 MySQL 版本)

MySQL 5.6 之前,DROP INDEX 会触发表重建,整个过程阻塞 DML;5.7+ 支持 ALGORITHM=INPLACE 的在线 DDL,但仍有条件限制:索引不是主键、不涉及全文 / 空间索引、且表引擎为 InnoDB。

执行前务必确认版本和存储引擎,否则可能在高峰期卡住业务写入。

  • 安全写法(显式指定算法):
    ALTER TABLE t1 DROP INDEX idx_name, ALGORITHM=INPLACE, LOCK=NONE;
  • 若报错 ALGORITHM=INPLACE is not supported,说明不满足条件,得切到低峰期用 ALGORITHM=COPY(会锁表)
  • 主键索引不能用 DROP INDEX 删除,必须用 ALTER TABLE …… DROP PRIMARY KEY,且会重建聚簇索引,代价极高

删除索引后写入变快,但某些查询可能陡然变慢

索引本质是“以空间换时间”的冗余结构。删掉一个索引,INSERT/UPDATE/DELETE 的维护开销下降,但原本走索引的 WHEREORDER BYJOIN 可能退化为文件排序或临时表,CPU 和 I/O 压力反而上升。

尤其要注意覆盖索引场景:如果一个 SELECT a,b FROM t WHERE c=? 原本命中 (c,a,b) 覆盖索引,删掉后变成回表 + 排序,延迟可能翻几倍。

  • 删索引前,用 EXPLAIN FORMAT=JSON 对核心 SQL 重跑执行计划,比对 keyrowsextra 字段变化
  • 监控删索引后 Handler_read_rnd_next(随机读行数)和 Sort_merge_passes 是否激增
  • 批量导入场景下,可临时删非关键索引加速写入,但导入完必须立刻重建——别忘了

唯一索引与外键约束不能随便删

唯一索引(含主键)不只是性能结构,更是数据完整性保障。删掉唯一索引后,应用层插入重复值不会报错,直到唯一约束失效引发脏数据;外键索引被删会导致 ALTER TABLE …… DROP FOREIGN KEY 失败,因为 MySQL 要求外键字段必须有索引支撑。

这类索引哪怕“看起来没被查询用”,也不能按普通索引处理。

  • 检查是否为外键索引:
    SELECT CONSTRAINT_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME = 't' AND REFERENCED_TABLE_NAME IS NOT NULL;
  • 检查是否为唯一约束:SHOW CREATE TABLE t 中找 UNIQUE KEYPRIMARY KEY
  • 真要删,必须同步评估业务逻辑能否容忍重复、级联操作是否可控、下游服务是否依赖该约束语义

真正难的不是语法怎么写,是判断“这个索引到底是不是冗余”——它可能在某个凌晨三点的报表任务里悄悄扛着压力,也可能在某个未覆盖的异常分支里唯一生效。删之前,看数据,看执行计划,看监控曲线,别信名字,也别信直觉。

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-06发表,共计1850字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources