pt-duplicate-key-checker能识别duplicate(完全相同列顺序、类型、排序方向)和redundant(前缀覆盖,如index(a,b)与index(a))两类索引问题,但默认不跨索引类型比对。

pt-duplicate-key-checker 能识别哪几类重复索引
它默认只比对同类型索引(比如都为 BTREE),能准确发现两类问题:duplicate(完全相同的列顺序+类型+排序方向)和 redundant(前缀关系,如已有 INDEX idx_a_b (a,b),又建了 INDEX idx_a (a))。但不会把 INDEX idx_a_hash (a) USING HASH 当成 BTREE 的冗余,也不会误判 FULLTEXT 索引。
运行前必须确认的三件事
别直接在生产库上跑 pt-duplicate-key-checker 就删索引。先做这几件事:
- 确保账号有
SELECT权限访问information_schema.STATISTICS和目标库表结构 - 用
SHOW CREATE TABLE your_table\G手动核对工具输出里提到的索引定义,特别是sub_part(前缀长度)、collation(排序规则)是否真一致 - 检查该表是否有被
EXPLAIN依赖的索引——比如某个慢查明确走idx_last_name,而工具建议删掉它,就得先验证EXPLAIN SELECT ... USE INDEX(...)是否仍能接受性能
执行命令时的关键参数组合
基础命令是 pt-duplicate-key-checker --host=localhost --user=readonly --password=xxx --databases=mydb,但实际要用好得加这些:
-
--ask-pass:避免密码明文出现在命令行或历史记录里 -
--no-version-check:跳过远程版本检查,加快启动(尤其内网环境) -
--quiet:减少冗余输出,只留建议语句,方便重定向到文件再人工审核 -
--filter '($row->{Index_comment} || "") !~ /keep/i':跳过带COMMENT 'keep'的索引(适合标记“暂不处理”的索引)
注意:它不会自动执行 DROP INDEX,只输出建议语句,这点很关键——你得自己 copy-paste 并加 IF EXISTS 防错。
删完索引后最容易被忽略的验证点
很多人删完就以为结束了,但 InnoDB 的索引删除不是瞬间完成的,尤其大表:
- 用
SHOW INDEX FROM your_table确认索引名确实没了,而不是只看工具输出 - 观察
INFORMATION_SCHEMA.INNODB_METRICS中的dml_reads、dml_writes是否在删索引后有明显下降(说明写入开销确实在减少) - 特别注意
TEXT/BLOB字段上的前缀索引——即使没被标为冗余,它们本身就会额外维护哈希结构,删掉一个冗余索引可能只是缓解,没解决根本膨胀
真正影响大的,往往不是多一个 idx_id,而是多个索引共同指向同一组大字段,导致聚簇索引外的二级索引体积翻倍增长。











