表结构如下:
create table test_index_efficient (
id int PRIMARY key not null auto_increment,
`name` VARCHAR(20),
`sex` VARCHAR(10),
country varchar(20),
age int(20)
)ENGINE=INNODB CHARSET=UTF8;
1.在解释之前先说明一下explain里面的字段
字段 | 名称 | 解释 |
---|---|---|
id | id | select的序列编号 |
select_type | select_type | 表示是简单还是复杂的查询 |
table | table | 表示explain行正在访问的哪个表 |
partitions | partitions | 表示的是当前查询访问的是哪个分区,一般是基于分区表 |
type | type | 表示当前表内的访问方式 |
possible_keys | possible_keys | 当前查询可能使用到的索引 |
key | key | 经过优化器评估最后使用的索引 |
key_len | key_len | 使用到的索引的长度 |
ref | ref | 表示引用到的列 |
rows | rows | 得到最终结果查询在表里面扫描的记录数 |
filtered | filtered | 表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数 |
Extra | extra | 额外的信息 |
其中在优化时需要关注的字段是
type:
这一列表示关联类型或访问类型,即mysql决定如何查找表中的行
性能优先级依次从最优到最差分别为:system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all
1.null:mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。
2.const、system:mysql能对查询的某部分进行优化并将其转化成一个常量(可以看show warnings的结果)。
3.eq_ref:primary key 或unique key索引的所有部分被连接使用,最多只会返回一条符合条件的记录。
4.ref:相比eq_ref,不实用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要喝某个值相比较,可能会找到符合条件的行。
5.ref_or_null:类似ref,但是可以搜索值为null的行。
6.index_merge:表示使用了索引合并的优化方法。
7.range:范围扫描通常出现在in(),between,>,<,>=等操作中。
8.index:和all一样,不同就是mysql只需扫描索引树,这通常比all快一些。
9.all:全表扫描,意味着mysql需要从头到尾去查找所需要的行,通常情况下这需要增加索引来进行优化了。
key_len:
用于处理查询的索引长度;越短速度越快;
extra:
1.distinct:一但mysql找到了与行相联合和匹配的行,就不再搜索了。
2.using index:这发生在对表的请求列都是同一索引的部分的时候,返回的列数据只使用了索引中的信息,而没有再去访问表中的行记录。(是性能高的表现)
3.using where:mysql服务器将在存储引擎检索行后再进行过滤。就是先读取整行数据,再按where条件进行检查,符合就留下,不符合就丢弃。
4.using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化。
5.using filesort:mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。此时mysql会根据联接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行信息。这种情况下一般也是要考虑使用索引来优化的。
rows:
越少越好,扫描的记录越少、越接近结果条数越好。