MySQL优化——使用explain来分析sql语句

MySQL为我们提供了一个分析sql语句执行计划的利器,那就是explain。通过explain我们可以分析一个sql语句完整的执行计划,包括使用的索引,扫描的行数以及是否使用了文件排序等等,在我们分析sql语句,优化sql语句中具有重要的意义。我们使用explain来查看生成一条sql语句的执行计划:

mysql> explain select * from hat_area;
+----+-------------+----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | hat_area | ALL  | NULL          | NULL | NULL    | NULL | 3144 | NULL  |
+----+-------------+----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

下面我们来一一解释这些字段是什么意思。

id

select查询标识符,一般不重要。一个select语句中可能会有多个子查询语句,为每一个查询语句生成一个id标识符。在使用了union连接符的情况下,id可能为null,比如:

explain select * from hat_city where cityID='110100' union select * from hat_area where areaID='110101';
+----+--------------+------------+------+---------------+------+---------+------
| id | select_type  | table      | type | possible_keys | key  | key_len | ref  | rows | Extra           |
+----+--------------+------------+------+---------------+------+---------+------
|  1 | PRIMARY      | hat_city   | ALL  | NULL          | NULL | NULL    | NULL |  345 |Using where     |
|  2 | UNION        | hat_area   | ALL  | NULL          | NULL | NULL    | NULL | 3144 |Using where     |
|NULL| UNION RESULT |<union1,2>  | ALL  | NULL         | NULL | NULL     | NULL | NULL |Using temporary |
+----+--------------+------------+------+---------------+------+---------+------
3 rows in set (0.08 sec)

使用union时生成了一张

select_type

表明查询的类型。可能有一下几个值:
simple:简单的查询,没有使用union或者子查询。
primary:最外层的select查询。
union:union连接符连接的第二个或者更后面的查询。
dependent union:同union,只是这个查询会依赖其他查询。
subquery:子查询中的第一个select。
dependent subquery:子查询中的第一个select,只是这个查询需要依赖其他查询。
derived:衍生表,子查询中from的子查询。
union result:union的结果。

table

每一个查询查询时使用的表名,这里的表名可能会有以下几个值:
真实的表名:即你在select语句中查询的那个表的表名。

possible_keys

可能使用到的索引,不是最终使用的索引。如果为null,表明没有相关的索引。

key

查询中真正使用的索引。

key_len

MySQL使用的索引的长度。在能保证区分度的情况下,索引的长度越短越好。

ref

哪些列或者常数用来跟索引比较来确定返回的行。如果是使用了固定的值,比如select * from table_test where id=5,这个值会是const。如果使用了某些函数,这个值会是func。

rows

sql执行过程中需要扫描到的行数。对于innodb引擎来说,这个值通常是一个估计值。这个值越小越好。

type

表明查询过程中表是如何连接的。下面列举了type可能的类型,性能从最优到最差:

  • system

查询的表中只有一行数据。通常不会出现。

  • const

查询的表中只有一条符合条件的记录。当你使用主键或者unique index为查询条件的时候,MySQL能够帮你迅速定位到你需要的那一条数据,这个时候的type就是const。

  • eq_ref

除了system和const之外,效率最好的一种。当你在查询时使用的查询条件或者连接条件都是primary key或者unique index,类型就是eq_ref.(每一个查询条件或者连接条件可以唯一定位到一条记录)

  • ref

当你在查询时,查询条件或者连接条件不是primary key或unique index,类型就会是ref(无法每次都定位到唯一的一条记录).

  • fulltext

使用了全文索引。

  • ref_or_null

类似于ref,但是查询条件中包含了NULL值。比如:

SELECT * FROM ref_table
  WHERE key_column=expr OR key_column IS NULL;
  • index merge

MySQL使用了多个索引,并且将索引进行了合并。这个时候key列会有多个索引。

  • unique_subquery

查询中使用了in子查询。in子查询中查询出来的都是primary key或者unique index。类似下面这样:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
  • index_subquery

类似于unique_subquery.in查询中查询出来的不是唯一索引。类似下面这样:

value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range

在索引上使用了范围查询。

  • index

查询过程中扫描了全部的索引。

  • ALL

查询过程中扫描了整个表。

Extra

包含了一些额外的信息。比如是否使用了文件排序等等。重点说下面几个。
using index:不需要回表查询数据,请求的数据都是索引中已经有的字段。
Using where:通过回表查询数据。
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”
Using join buffer:强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。

你可能感兴趣的:(技术博客,数据库)