冗余索引和未使用索引的危害
随着上线的业务越来越多,在MySQL数据库中建的表也会越来越多,为提高查询访问速度,会创建相应的索引。但是由于技术人员的水平参差不齐,业务下线,代码逻辑变更等原因,导致线上数据库会有冗余索引或者从未使用的索引存在,这些索引不仅消耗大量的磁盘空间,而且还会影响数据库的insert,update性能,因此作为数据库管理人员,需要及时发现这些冗余索引和未使用索引,并及时清理。
冗余索引和未使用索引定位
要找出线上数据库的冗余索引和未使用索引,使用工具,会让你事半功倍,例如percona-toolkits工具集就提供pt-duplicate-key-checker和pt-index-usage就能非常方便找出数据库的冗余索引和未使用索引。
在MySQL5.7的版本sys模式下,schema_redundant_indexes和schema_unused_indexes两个视图,更方便直接的展示,个人感觉比pt-duplicate-key-checker和pt-index-usage的方便和准确。
下面就来具体查看一下相关信息。
找重复索引,并提供drop index语句
mysql> select * from schema_redundant_indexesG;*************************** 1. row *************************** table_schema: sbtest table_name: sbtest1 redundant_index_name: k_1 redundant_index_columns: kredundant_index_non_unique: 1 dominant_index_name: idx_sbtest1_k dominant_index_columns: k dominant_index_non_unique: 1 subpart_exists: 0 sql_drop_index: ALTER TABLE `sbtest`.`sbtest1` DROP INDEX `k_1`*************************** 2. row *************************** table_schema: sbtest table_name: sbtest1 redundant_index_name: idx_sbtest1_id_k redundant_index_columns: id,kredundant_index_non_unique: 1 dominant_index_name: PRIMARY dominant_index_columns: id dominant_index_non_unique: 0 subpart_exists: 0 sql_drop_index: ALTER TABLE `sbtest`.`sbtest1` DROP INDEX `idx_sbtest1_id_k`
在这里确认一下,这个视图找出来的重复index是否准确,看看sbtest.sbtest1的表结构
mysql> show create table sbtest.sbtest1G;*************************** 1. row *************************** Table: sbtest1Create Table: CREATE TABLE `sbtest1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `k` int(10) unsigned NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`), KEY `idx_sbtest1_id_k` (`id`,`k`), KEY `idx_sbtest1_k` (`k`)) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=utf8 MAX_ROWS=10000001 row in set (0.00 sec)
k_1,idx_sbtest1_id_k,idx_sbtest1_k三个索引确实是冲突了,系统建议保留idx_sbtest1_k这个索引。
来定位未使用索引
mysql> select * from schema_unused_indexes;+---------------+-------------+--------------------+| object_schema | object_name | index_name |+---------------+-------------+--------------------+| sbtest | sbtest1 | k_1 || sbtest | sbtest1 | idx_sbtest1_id_k || sbtest | sbtest1 | idx_sbtest1_k || sbtest | t_pay_test | k_1 || sbtest | t_pay_test | idx_t_pay_test_k_c |+---------------+-------------+--------------------+5 rows in set (0.00 sec)
删除未使用索引时,需要注意一下,建议每个月都获取一次,如果连续3个月都没有使用,可以删除掉。