导读:本期聚焦于小伙伴创作的《MySQL如何快速删除不再使用的索引?删除索引时有哪些风险需要规避》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《MySQL如何快速删除不再使用的索引?删除索引时有哪些风险需要规避》有用,将其分享出去将是对创作者最好的鼓励。

在MySQL数据库的长期运行过程中,随着业务需求变更,很多早期创建的索引会逐渐不再被查询使用,这些冗余索引不仅会占用额外的磁盘空间,还会在数据插入、更新、删除时增加索引维护的成本,拖慢整体数据库性能。定期清理无用索引是数据库优化中投入产出比很高的操作,不过需要掌握正确的方法和风险规避策略。

MySQL如何快速删除不再使用的索引?删除索引时有哪些风险需要规避

如何快速定位不再使用的索引

要删除无用索引,首先需要准确识别哪些索引已经不再被使用,MySQL提供了多种方式帮助我们完成这个工作。

利用performance_schema统计索引使用情况

MySQL的performance_schema库中有专门的表记录索引的使用情况,我们可以通过查询table_io_waits_summary_by_index_usage表来获取索引的使用数据,没有被使用的索引对应的COUNT_READCOUNT_WRITE等字段值会长期为0。

以下是查询指定库中未使用索引的示例SQL:

-- 查询test库中未被使用的索引
SELECT 
    OBJECT_SCHEMA AS 库名,
    OBJECT_NAME AS 表名,
    INDEX_NAME AS 索引名,
    COUNT_READ AS 读取次数,
    COUNT_WRITE AS 写入次数
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = 'test'
    AND INDEX_NAME IS NOT NULL
    AND COUNT_READ = 0
    AND COUNT_WRITE = 0
    AND INDEX_NAME != 'PRIMARY';

使用pt-index-usage工具分析慢查询日志

Percona Toolkit中的pt-index-usage工具可以分析慢查询日志,统计哪些索引被查询使用过,未被提及的索引大概率是无用索引。使用该工具前需要先开启慢查询日志,执行以下命令开启:

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
-- 设置慢查询阈值,单位秒
SET GLOBAL long_query_time = 1;
-- 设置慢查询日志存储位置
SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';

然后执行工具分析日志:

pt-index-usage /var/lib/mysql/slow.log --host=127.0.0.1 --user=root --password=123456

快速删除无用索引的操作方法

确认索引无用后,可以使用DROP INDEX语句快速删除索引,语法格式如下:

-- 删除普通索引
DROP INDEX 索引名 ON 表名;
-- 删除主键索引(需要特殊处理)
ALTER TABLE 表名 DROP PRIMARY KEY;

如果需要批量删除多个无用索引,可以拼接删除语句,以下是生成批量删除语句的示例:

-- 生成删除test库无用索引的批量语句
SELECT 
    CONCAT('DROP INDEX ', INDEX_NAME, ' ON ', TABLE_NAME, ';') AS 删除语句
FROM (
    SELECT 
        OBJECT_NAME AS TABLE_NAME,
        INDEX_NAME AS INDEX_NAME
    FROM performance_schema.table_io_waits_summary_by_index_usage
    WHERE OBJECT_SCHEMA = 'test'
        AND INDEX_NAME IS NOT NULL
        AND COUNT_READ = 0
        AND COUNT_WRITE = 0
        AND INDEX_NAME != 'PRIMARY'
) AS tmp;

索引删除的风险及规避方案

删除索引看似操作简单,但如果处理不当会引发严重的业务问题,以下是常见的风险和对应的规避方法。

风险1:误删仍被使用的索引,导致查询性能骤降

如果索引实际还在被部分低频查询使用,误删后这些查询会转为全表扫描,查询耗时可能从毫秒级上升到秒级甚至分钟级,严重影响业务响应速度。

规避方案:删除前先确认索引的冷门程度,对于使用频率极低的索引,可以先将其重命名标记为待删除状态,观察1-2周业务无异常后再执行删除。重命名索引的示例:

-- 重命名索引,标记为待删除
ALTER TABLE test.user_table RENAME INDEX idx_old TO idx_old_to_drop;

风险2:删除索引时锁表,影响线上业务写入

在MySQL 5.7及之前的版本中,删除索引的操作会对表加元数据锁,如果表数据量很大,删除索引的过程可能持续较长时间,期间会阻塞表的写入操作,导致业务报错。

规避方案:尽量在业务低峰期执行删除操作,对于大表,可以使用Online DDL特性,MySQL 5.6及以上版本默认支持Online DDL删除索引,不会长时间阻塞写入。如果使用的是低版本MySQL,可以考虑使用pt-online-schema-change工具执行无锁删除。

风险3:删除主键索引导致数据完整性问题

主键索引是InnoDB表聚簇索引的基础,如果误删主键索引,且没有及时创建新的主键,会导致表没有聚簇索引,查询性能大幅下降,甚至可能出现数据重复的问题。

规避方案:删除主键前必须先确认表有其他唯一非空索引可以替代主键,或者提前创建新的主键索引,再删除旧的主键。删除主键的示例:

-- 先添加新主键
ALTER TABLE test.user_table ADD PRIMARY KEY (user_id);
-- 再删除旧主键(如果旧主键不是user_id)
ALTER TABLE test.user_table DROP PRIMARY KEY;

风险4:删除索引后未验证,后续问题排查困难

删除索引后如果没有做验证,后续出现查询性能问题时,很难第一时间联想到是索引删除导致的问题,增加排查成本。

规避方案:删除索引前后分别记录核心查询的耗时,删除后对比验证性能无异常,同时记录删除的索引名称、所属表、删除时间、操作人,方便后续追溯。

索引清理的最佳实践

为了保证索引清理的安全和高效,建议遵循以下实践流程:

  • 每月定期统计索引使用情况,筛选出连续30天无使用的索引作为待清理候选
  • 对待清理索引进行业务侧确认,排除低频但必要的业务查询使用的索引
  • 先在测试环境模拟删除操作,验证无问题后再到生产环境执行
  • 生产环境删除操作选择凌晨等业务低峰期执行,提前做好数据库备份
  • 删除后持续观察1周业务查询性能和错误日志,确认无异常后完成清理

通过以上方法,我们可以在规避风险的前提下,快速完成MySQL无用索引的清理,提升数据库的整体运行效率。

MySQL索引删除索引清理数据库优化修改时间:2026-07-09 08:51:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。