执行计划的字段
id
- id 相同,执行顺序由上至下
- id 不同,如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行
- id 相同、不同都存在,则相同的时一组,由上至下顺序执行,所有组中,id 值越大越先执行
select_type
类型 | 描述 |
---|---|
SIMPLE | 简单的select查询,不包含子查询或者union |
PRIMARY | 查询中若包含任何复杂的子部分,最外层查询则被标记为primary |
SUBQUERY | 在select或where列表中包含了子查询 |
DERIVED | 在from列表中包含的子查询被标记为derived(衍生),MySQL会递归执行这些子查询,把结果放在临时表里 |
UNION | 若第二个select出现在union之后,则被标价为union;若union包含在from子句的子查询中,外层select将被标记为derived |
UNION RESULT | 从union表获取结果的select |
table
显示这一行的数据是关于哪张表的
type
显示访问类型,重要指标,从好到坏依次为
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
需要记忆的
system > const > eq_ref > ref > range > index > ALL
类型 | 描述 |
---|---|
system | 表只有一行记录(等于系统表),这是 const 的特例,平时不会出现 |
const | 表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快。 |
eq_ref | 唯一性索引扫描,对于每个索引键,表只有一条记录与之匹配。常见于主键或唯一索引扫描 |
ref | 非唯一性索引扫描,返回匹配某个单独值的所有行 |
range | 只检索给定范围的行,使用一个索引来选择行,key字段显示使用了哪个索引。一般就是 where 语句中出现了 between、<、>、in 等的查询 |
index | 当查询的结果全为索引列的时候 |
ALL | 什么索引也不用,全表查询以找到匹配的行 |
possible_keys
可能用到的索引
key
- 实际使用的索引,如果为 NULL,则没有使用索引
- 查询中若使用了覆盖索引,则该索引和查询的 select 字段重叠
key_len
- 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好。
- 它显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的。
- char 和 varchar 的长度与字符集编码有关,latin1 占 1 个字节,gbk 占 2 个字节,utf8 占 3 个字节。
字符串类型
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255 字节 | 定长字符串 |
VARCHAR | 0-65535 字节 | 变长字符串 |
TINYBLOB | 0-255 字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255 字节 | 短文本字符串 |
BLOB | 0-65535 字节 | 二进制形式的长文本数据 |
TEXT | 0-65535 字节 | 长文本数据 |
MEDIUMBLOB | 0-16777215 字节 | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16777215 字节 | 中等长度文本数据 |
LONGBLOB | 0-4294967295 字节 | 二进制形式的极大文本数据 |
LONGTEXT | 0-4294967295 字节 | 极大文本数据 |
ref
显示索引的哪一列被使用了,如果可能的话,是一个常数。
rows
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。
Extra
包含不适合在其他列中显示但十分重要的额外信息
值 | 描述 |
---|---|
Using filesort | 说明 MySQL 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL 中无法利用索引完成的排序操作称为“文件排序” |
Using temporary | 使用了临时表保存中间结果,MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by |
Using index | 是否用了覆盖索引 |
Using where | 表明使用了 where 过滤 |
Using join buffer | 使用了连接缓存 |
Impossible where | where 子句的值总是 false,不能用来获取任何元组 |
查询策略
尽量全值匹配
尽量使用全部的索引列查询
最佳左前缀法则
如果索引用了多列,要遵守最做前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。
不在索引列上做任何操作
不要做任何操作(计算、函数、类型转换),会导致索引失效而转向全表扫描
范围条件放最后
存储引擎不能使用索引中范围条件右边的列。
尽量使用覆盖索引
只访问索引的查询(索引列和查询列一致),减少 select *
不等于要慎用
MySQL 在使用不等于时候无法使用索引,会导致全表扫描
not / null 有影响
like 查询要当心
like 以通配符开头,MySQL 索引失效会变成全表扫描
字符类型加引号
字符串不加单引号索引失效