MySQL 索引优化笔记
一般通过explain查看语句执行效果:explain <sql语句>
其中的结果列含义:
-
id: 表示的是SQL语句的执行的顺序,SQL按照id从大到小的执行。当id相同时,表示是同一组,按照从上到下的顺序执行。
-
select_type: 指的是select语句的类型,主要有以下几种:
- SIMPLE 最简单的SELECT语句(不使用UNION或子查询等)
- PRIMAR 最外层的语句叫做PRIMARY
- UNION 当语句中存在UNION时,UNION中的第二个或后面的SELECT语句
- DEPENDENT UNION UNION中的第二个或后面的SELECT语句,取决于外面的查询结果
- SUBQUERY
子查询中的第一个SELECT,其结果不依赖于外面的查询结果 - DEPENDENT SUBQUERY
子查询中的第一个SELECT,依赖于外面的查询结果 - DERIVED当从一个中间结果进行FROM时,指的是派生表的SELECT(FROM子句的子查询)
-
table:标识的是这指定行数据是从哪张表获取的,临时表也在这个范围内
-
type 标示的是对表的访问方式,是否使用了索引,常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
-
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
-
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
-
range:只检索给定范围的行,使用一个索引来选择行
-
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
-
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
-
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
-
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
-
-
possible_keys:指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null。该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询
-
key:key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中,如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
-
key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)
-
ref:列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
-
rows:估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
-
Extra:该列包含MySQL解决查询的详细信息,有以下几种情况:
- Using index:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
- Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
- Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by
- Using filesort:查询语句包含order by,且无法利用索引完成排序,执行过程中使用临时文件进行排序
- Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
其它:
explain执行计划看到的是一个预估的值,而非实际准确的值
explain只能查看select查询语句
explain没有考虑使用查询缓存
索引失效场景:
- 数据表数据量较少,使用全表扫描效率可以接受的场景
- 更新操作频繁的数据表
- 区分度不高的字段,比如有效和无效
- 对于很少使用到的字段
- 现有索引前缀已经包括要创建索引涉及字段
- 字段类型为text、image等占用存储空间太大的类型
- 经常需要使用聚合函数计算的字段
- 经常需要使用模糊查询的字段
- 经常需要通过负向组合的查询语句,如:not、not in、not like、!=等