pt-duplicate-key-checker这款工具也是percona-toolkit中一款非常适用的工具,它可以帮助你检测表中重复的索引或者主键。我们知道索引会更查询带来好处,但是过量的索引反而可能会使数据库的性能降低,这款工具可以帮助我们找到重复的索引并且还会给你删除重复索引的建议语句,非常好用。
首先看我的这张表的索引结构
mysql> show indexes from curs;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| curs | 0 | PRIMARY | 1 | id | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | name | 1 | name | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | age | 1 | age | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | name_age | 1 | name | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | name_age | 2 | age | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | age_name | 1 | age | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | age_name | 2 | name | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | name_1 | 1 | name | A | 1 | NULL | NULL | | BTREE | | |
| curs | 1 | age_1 | 1 | age | A | 1 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
里面有大量的重复索引,比如name与name_age重复,也与name_1重复,这3个索引都是相同的索引。下面看下怎么使用/usr/local/bin/pt-duplicate-key-checker来检查重复的索引。
[root@localhost ~]# /usr/local/bin/pt-duplicate-key-checker --host=192.168.1.106 --user='mysql' --password='123456' --databases=test --tables=curs
# ########################################################################
# test.curs
# ########################################################################
# name is a left-prefix of name_age
# Key definitions:
# KEY `name` (`name`),
# KEY `name_age` (`name`,`age`),
# Column types:
# `name` varchar(100) not null default ''
# `age` smallint(3) unsigned not null default '0'
# To remove this duplicate index, execute:
ALTER TABLE `test`.`curs` DROP INDEX `name`;
# name_1 is a left-prefix of name_age
# Key definitions:
# KEY `name_1` (`name`),
# KEY `name_age` (`name`,`age`),
# Column types:
# `name` varchar(100) not null default ''
# `age` smallint(3) unsigned not null default '0'
# To remove this duplicate index, execute:
ALTER TABLE `test`.`curs` DROP INDEX `name_1`;
# age is a left-prefix of age_name
# Key definitions:
# KEY `age` (`age`),
# KEY `age_name` (`age`,`name`),
# Column types:
# `age` smallint(3) unsigned not null default '0'
# `name` varchar(100) not null default ''
# To remove this duplicate index, execute:
ALTER TABLE `test`.`curs` DROP INDEX `age`;
# age_1 is a left-prefix of age_name
# Key definitions:
# KEY `age_1` (`age`)
# KEY `age_name` (`age`,`name`),
# Column types:
# `age` smallint(3) unsigned not null default '0'
# `name` varchar(100) not null default ''
# To remove this duplicate index, execute:
ALTER TABLE `test`.`curs` DROP INDEX `age_1`;
# ########################################################################
# Summary of indexes
# ########################################################################
# Size Duplicate Indexes 608
# Total Duplicate Indexes 4
# Total Indexes 7
这里面有一处很有意思的地方是,为什么删除name,name_age与name_1这3个重复索引的时候没有删除name_age这个组合索引呢?因为现在的索引设计尽可能的设计成组合索引,而不要单独的列进行索引,所以pt-duplicate-key-checker在判断的时候尽可能的让组合索引保持下来。下面还记录了重复索引占用了多少大小,重复索引的个数以及总共的索引数目。
pt-duplicate-key-checker中还有很多其它的选项与参数,可以通过/usr/local/bin/pt-duplicate-key-checker --help查看