在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。
mysql中支持hash和btree索引。innodb和myisam只支持btree索引,而memory和heap存储引擎可以支持hash和btree索引
1. 查看当前索引使用情况
我们可以通过下面语句查询当前索引使用情况:

其实比较多应用场景是当索引正在工作,Handler_read_key的值将很高,这个值代表了一个行将索引值读的次数,很低的值表明增加索引得到的性能改善不高,因为索引并不经常使用。
Handler_read_rnd_next 的值高则意味着查询运行低效,并且应该建立索引补救。这个值的含义是在数据文件中读下一行的请求数。如果正进行大量的表 扫描,Handler_read_rnd_next的值较高,则通常说明表索引不正确或写入的查询没有利用索引
2. 查看索引是否被使用到
- SELECT
- object_type,
- object_schema,
- object_name,
- index_name,
- count_star,
- count_read,
- COUNT_FETCH
- FROM
- PERFORMANCE_SCHEMA.table_io_waits_summary_by_index_usage;
如果read,fetch的次数都为0的话,就是没有被使用过的。


3. 查看使用了哪些索引
explain相关sql,查看type表示查询用到了那种索引类型
- +-----+-------+-------+-----+--------+-------+---------+-------+
- | ALL | index | range | ref | eq_ref | const | system | NULL |
- +-----+-------+-------+-----+--------+-------+---------+-------+
从最好到最差依次是:
- system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
顺便提几个优化注意点:
(1) 优化insert语句:
(2) 优化group by语句:
默认情况下,mysql会对所有group by字段进行排序,这与order by类似。如果查询包括group by但用户想要避免排序结果的消耗,则可以指定order by null禁止排序。
(3) 优化order by语句:
某些情况下,mysql可以使用一个索引满足order by字句,因而不需要额外的排序。where条件和order by使用相同的索引,并且order by的顺序和索引的顺序相同,并且order by的字段都是升序或者降序。
(4) 优化嵌套查询:
mysql4.1开始支持子查询,但是某些情况下,子查询可以被更有效率的join替代,尤其是join的被动表待带有索引的时候,原因是mysql不需要再内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。
最后提一个点:
一个表最多16个索引,最大索引长度256字节,索引一般不明显影响插入性能(大量小数据例外),因为建立索引的时间开销是O(1)或者O(logN)。不过太多索引也是不好的,毕竟更新之类的操作都需要去维护索引。