生产环境清理重复索引推荐使用 Percona Toolkit 中的 pt-duplicate-key-checker 工具,该工具通过扫描 information_schema 识别完全重复或前缀冗余的索引并生成删除建议语句。重要风险边界是工具仅输出建议 SQL,必须人工验证索引未被业务查询依赖后方可执行删除操作。
先说结论:pt-duplicate-key-checker 能安全识别重复和冗余索引,但不能直接自动删除,需结合业务查询验证。
- 先定位:使用工具扫描数据库,导出重复索引报告。
- 先做:核对 performance_schema 确认索引未被活跃查询使用。
- 再验证:执行删除后观察慢查询日志和业务响应时间。
命令速用版
基础检查命令需指定连接信息并开启密码交互提示,避免密码泄露。
pt-duplicate-key-checker `--host`=localhost `--user`=readonly `--ask-pass` `--databases`=mydb `--quiet` > duplicate_indexes.sql生产环境建议增加过滤参数跳过标记为保留的索引,并跳过版本检查以加快启动。
pt-duplicate-key-checker `--host`=localhost `--user`=readonly `--ask-pass` `--no-version-check` `--quiet` `--filter` '($row->{Index_comment} || "") !~ /keep/i'为什么会这样
重复索引会增加写入开销并干扰优化器选择,导致磁盘空间和 IO 浪费。
工具能识别两类问题:duplicate 指列顺序、类型、排序方向完全相同的索引;redundant 指前缀覆盖关系,如已有 INDEX(a,b) 又建了 INDEX(a)。
默认情况下工具只比对同类型索引(如 BTREE 对 BTREE),不会误判 FULLTEXT 或 HASH 索引为冗余。
分步处理
第一步确认账号权限,需授予 SELECT 权限访问 information_schema.STATISTICS 和目标库表结构,部分环境还需 PROCESS 权限。
第二步运行工具生成报告,不要直接在生产库管道执行删除命令,先将输出重定向到文件人工审核。
第三步验证索引使用情况,MySQL 8.0+ 可查询 performance_schema.table_io_waits_summary_by_index_usage 表,确认 COUNT_STAR 和 COUNT_READ 均为 0。
第四步执行删除语句,手动复制工具生成的 ALTER TABLE DROP INDEX 语句,并建议添加 IF EXISTS 防错。
ALTER TABLE `mydb`.`mytable` DROP INDEX IF EXISTS `idx_duplicate`;怎么验证是否生效
删除后使用 SHOW INDEX FROM table_name 确认索引列表已更新,重复项消失。
观察慢查询日志,确认没有因索引缺失导致的新增慢查询出现。
对于关键表,使用 EXPLAIN SELECT 验证原有查询是否仍能走预期的剩余索引。
常见坑
权限不足会导致 Access denied 报错,必须确保账号能读取 information_schema 和目标库元数据。
连接超时常见于大库,可加参数 `--set-vars` wait_timeout=28800 延长等待时间。
MySQL 8.0+ 默认 caching_sha2_password 认证可能失败,需改用 mysql_native_password 或通过 `--defaults-file` 指定配置文件。
唯一索引或被外键依赖的索引即使显示冗余也不可直接删除,需确认业务逻辑不依赖其唯一性约束。
常见问题
duplicate 和 redundant 有什么区别
duplicate 是完全相同的索引定义,redundant 是前缀覆盖关系。
工具输出的 SQL 可以直接执行吗
不可以,必须先验证该索引是否被业务查询实际使用。
支持 MySQL 8.0 及以上版本吗
支持,但需注意认证插件兼容性,必要时调整用户认证方式。
参考来源
- Percona Toolkit Official Documentation: pt-duplicate-key-checker, http://www.percona.com/doc/percona-toolkit/pt-duplicate-key-checker.html
- 技术文章:mysql 如何处理重复索引带来的开销_使用 pt-duplicate-key-checker
- 技术文章:mysql 如何处理重复索引与冗余索引_使用 pt-duplicate-key-checker