我们用explain检查sql语句的性能,触发索引的实际情况
explain显示的内容如下
mysql> explain SELECT * from statuses where user_id=1 ;
+----+-------------+----------+------------+------+------------------------+------------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+------------------------+------------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | statuses | NULL | ref | statuses_user_id_index | statuses_user_id_index | 4 | const | 29 | 100.00 | NULL |
+----+-------------+----------+------------+------+------------------------+------------------------+---------+-------+------+----------+-------+
1 row in set (0.00 sec)
有12列信息
- id:选择标识符
- select_type:表示查询的类型。
- table:输出结果集的表
- partitions:匹配的分区
- type:表示表的连接类型
- possible_keys:表示查询时,可能使用的索引
- key:表示实际使用的索引
- key_len:索引字段的长度
- ref:列与索引的比较
- rows:扫描出的行数(估算的行数)
- filtered:按表条件过滤的行百分比
- Extra:执行情况的描述和说明
我们需要重点关注的信息包括
- type
这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行。
依次从最优到最差分别为:system > const > eq_ref > ref > fulltext >
ref_or_null > index_merge > unique_subquery >
index_subquery > range > index > ALL
NULL不需要访问表
index全索引扫描
All意味着全表扫描,需要进行优化
- possible_keys
这一列表示可能使用的索引
explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。
如果该列是NULL,则没有相关的索引。
在这种情况下,可以通过检查 where 子句看是否可以创造一个适当的索引来提高查询性能,然后用 explain 查看效果。
- key
表示实际使用的索引
如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 force index、ignore index。
- key_len
这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
举例来说,film_actor的联合索引 idx_film_actor_id 由 film_id 和 actor_id 两个int列组成,并且每个int是4字节。
通过结果中的key_len=4可推断出查询使用了第一个列:film_id列来执行索引查找。
不损失精确性的情况下,长度越短越好
- rows
预计查询需要扫描的行数(表或索引树中)
- filtered
存储引擎返回给mysql的后,MYSQL server层过滤后,剩余满足条件的行数占比
- extra 重要
出现则需要优化的
1. Using filesort
说明mysql无法利用索引排序,进行了额外的排序
2. Using temporary
使用的临时表
另外 Using index
使用索引覆盖,不需要扫描原表,直接通过索引扫描就能得到想要的数据。性能高
参考文章
MySQL EXPLAIN 输出信息解读