[转]Mysql Explain 详解

本文转自:http://www.cnitblog.com/aliyiyi08/archive/2008/09/09/48878.html

一.语法

explain < table_name >

例如: explain select * from t3 where id=3952602;

二.explain输出解释

+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
| id | select_type | table | type  | possible_keys     | key     |
key_len | ref   | rows | Extra |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+

1.id
  我的明亮是SQL执行的顺利的标识,SQL从那个及多少的执行.

例如:
mysql> explain select * from (select * from ( select * from t3
where id=3952602) a) b;
+—-+————-+————+——–+——————-+———+———+——+——+——-+
| id | select_type | table      | type   | possible_keys     | key 
   | key_len | ref  | rows | Extra |
+—-+————-+————+——–+——————-+———+———+——+——+——-+
|  1 | PRIMARY     | <derived2> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY
| 4       |      |    1 |       |
+—-+————-+————+——–+——————-+———+———+——+——+——-+

老大扎眼这条SQL是打里往他之执行,就是由id=3 向上执行.

  1. select_type

虽select类型,可以发以下几种

(1) SIMPLE
概括SELECT(不使UNION或子查询等) 例如:
mysql> explain select * from t3 where id=3952602;
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
| id | select_type | table | type  | possible_keys     | key     |
key_len | ref   | rows | Extra |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4 
     | const |    1 |       |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+

(2). PRIMARY

自身的掌握是最最外层的select.例如:

mysql> explain select * from (select * from t3 where id=3952602) a
;
+—-+————-+————+——–+——————-+———+———+——+——+——-+
| id | select_type | table      | type   | possible_keys     | key 
   | key_len | ref  | rows | Extra |
+—-+————-+————+——–+——————-+———+———+——+——+——-+
|  1 | PRIMARY     | <derived2> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY
| 4       |      |    1 |       |
+—-+————-+————+——–+——————-+———+———+——+——+——-+

(3).UNION

UNION中的第二单或后的SELECT语句.例如
mysql> explain select * from t3 where id=3952602 union all select *
from t3 ;
+—-+————–+————+——-+——————-+———+———+——-+——+——-+
| id | select_type  | table      | type  | possible_keys     | key 
   | key_len | ref   | rows | Extra |
+—-+————–+————+——-+——————-+———+———+——-+——+——-+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY
| 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    |
NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              |
NULL    | NULL    | NULL  | NULL |       |
+—-+————–+————+——-+——————-+———+———+——-+——+——-+

(4).DEPENDENT UNION

UNION中的老二个或后的SELECT语句,取决于外面的查询

mysql> explain select * from t3 where id in (select id from t3 where
id=3952602 union all select id from t3)  ;
+—-+——————–+————+——–+——————-+———+———+——-+——+————————–+
| id | select_type        | table      | type   | possible_keys     |
key     | key_len | ref   | rows | Extra                    |
+—-+——————–+————+——–+——————-+———+———+——-+——+————————–+
|  1 | PRIMARY            | t3         | ALL    | NULL              |
NULL    | NULL    | NULL  | 1000 | Using where              |
|  2 | DEPENDENT SUBQUERY | t3         | const  | PRIMARY,idx_t3_id |
PRIMARY | 4       | const |    1 | Using index              |
|  3 | DEPENDENT UNION    | t3         | eq_ref | PRIMARY,idx_t3_id |
PRIMARY | 4       | func  |    1 | Using where; Using index |
|NULL | UNION RESULT       | <union2,3> | ALL    | NULL          
   | NULL    | NULL    | NULL  | NULL |                          |
+—-+——————–+————+——–+——————-+———+———+——-+——+————————–+

(4).UNION RESULT

UNION的结果。

mysql> explain select * from t3 where id=3952602 union all select *
from t3 ;
+—-+————–+————+——-+——————-+———+———+——-+——+——-+
| id | select_type  | table      | type  | possible_keys     | key 
   | key_len | ref   | rows | Extra |
+—-+————–+————+——-+——————-+———+———+——-+——+——-+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY
| 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    |
NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              |
NULL    | NULL    | NULL  | NULL |       |
+—-+————–+————+——-+——————-+———+———+——-+——+——-+

(5).SUBQUERY

分层查询中的首先独SELECT.

mysql> explain select * from t3 where id = (select id from t3 where
id=3952602 )  ;
+—-+————-+——-+——-+——————-+———+———+——-+——+————-+
| id | select_type | table | type  | possible_keys     | key     |
key_len | ref   | rows | Extra       |
+—-+————-+——-+——-+——————-+———+———+——-+——+————-+
|  1 | PRIMARY     | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4 
     | const |    1 |             |
|  2 | SUBQUERY    | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4 
     |       |    1 | Using index |
+—-+————-+——-+——-+——————-+———+———+——-+——+————-+

(6).  DEPENDENT SUBQUERY

旁查询中之率先单SELECT,取决于外面的查询

mysql> explain select id from t3 where id in (select id from t3 where
id=3952602 )  ;
+—-+——————–+——-+——-+——————-+———+———+——-+——+————————–+
| id | select_type        | table | type  | possible_keys     | key 
   | key_len | ref   | rows | Extra                    |
+—-+——————–+——-+——-+——————-+———+———+——-+——+————————–+
|  1 | PRIMARY            | t3    | index | NULL              | PRIMARY
| 4       | NULL  | 1000 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | t3    | const | PRIMARY,idx_t3_id |
PRIMARY | 4       | const |    1 | Using index              |
+—-+——————–+——-+——-+——————-+———+———+——-+——+————————–+

(7).DERIVED

派生表的SELECT(FROM子句的子查询)

mysql> explain select * from (select * from t3 where id=3952602) a
;
+—-+————-+————+——–+——————-+———+———+——+——+——-+
| id | select_type | table      | type   | possible_keys     | key 
   | key_len | ref  | rows | Extra |
+—-+————-+————+——–+——————-+———+———+——+——+——-+
|  1 | PRIMARY     | <derived2> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY
| 4       |      |    1 |       |
+—-+————-+————+——–+——————-+———+———+——+——+——-+

3.table

亮这无异于推行之数量是关于哪张表的.
奇迹不是忠实的表名字,看到的凡derivedx(x是单数字,我之知晓是第几步执行的结果)

mysql> explain select * from (select * from ( select * from t3
where id=3952602) a) b;
+—-+————-+————+——–+——————-+———+———+——+——+——-+
| id | select_type | table      | type   | possible_keys     | key 
   | key_len | ref  | rows | Extra |
+—-+————-+————+——–+——————-+———+———+——+——+——-+
|  1 | PRIMARY     | <derived2> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY
| 4       |      |    1 |       |
+—-+————-+————+——–+——————-+———+———+——+——+——-+

4.type

当即排好重要,显示了连续使用了啦种档次,有无使用索引.
于不过好及最好差的连天路为const、eq_reg、ref、range、indexhe和ALL

(1).system

立是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上之id是
primary key)

mysql> explain select * from (select * from t3 where id=3952602) a
;
+—-+————-+————+——–+——————-+———+———+——+——+——-+
| id | select_type | table      | type   | possible_keys     | key 
   | key_len | ref  | rows | Extra |
+—-+————-+————+——–+——————-+———+———+——+——+——-+
|  1 | PRIMARY     | <derived2> | system | NULL              |
NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY
| 4       |      |    1 |       |
+—-+————-+————+——–+——————-+———+———+——+——+——-+

(2).const

发明最多发生一个配合配行,它用以询问开始经常吃读取。因为只来一行,在这行的列值可让优化器剩余部分认为是常数。const表很快,因为它们只是念博一不好!

const用于用常数值比较PRIMARY
KEY或UNIQUE索引的有片段经常。在下面的询问中,tbl_name可以用于const表:
SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和
primary_key_part2=2;

例如:
mysql> explain select * from t3 where id=3952602;
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
| id | select_type | table | type  | possible_keys     | key     |
key_len | ref   | rows | Extra |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4 
     | const |    1 |       |
+—-+————-+——-+——-+——————-+———+———+——-+——+——-+

(3). eq_ref

于每个来自于前方的申的行组合,从该表中读取一行。这也许是最好之对接类型,除了const类型。它之所以当一个索引的持有片段于连接使用以索引是UNIQUE或PRIMARY
KEY。

eq_ref可以用来采取=
操作符比较的带索引的排列。比较值好啊常量或一个用以该表前面所读取的发明的排的表达式。

于脚的例证中,MySQL可以使eq_ref联接来拍卖ref_tables:

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如
mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+—-+————-+——-+——–+——————-+———–+———+———————-+——+——-+
| id | select_type | table | type   | possible_keys     | key       |
key_len | ref                  | rows | Extra |
+—-+————-+——-+——–+——————-+———–+———+———————-+——+——-+
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      |
NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id
| 4       | dbatest.t4.accountid |    1 |       |
+—-+————-+——-+——–+——————-+———–+———+———————-+——+——-+

(4).ref

对每个来自于前的说明的行组合,所有发生相当配索引值的即将从即张表中读取。如果连只使用键的最为左边的前缀,或只要果键不是UNIQUE或PRIMARY
KEY(换句话说,如果连不能够根据关键字选择么行的言辞),则应用ref。如果采取的键仅仅匹配少量履行,该联接类型是科学的。

ref可以用来采取=或<=>操作符的带索引的排列。

当脚的事例中,MySQL可以动用ref联接来处理ref_tables:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如:

mysql> drop index idx_t3_id on t3;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> create index idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.04 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+—-+————-+——-+——+——————-+———–+———+———————-+——+——-+
| id | select_type | table | type | possible_keys     | key       |
key_len | ref                  | rows | Extra |
+—-+————-+——-+——+——————-+———–+———+———————-+——+——-+
|  1 | SIMPLE      | t4    | ALL  | NULL              | NULL      |
NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | ref  | PRIMARY,idx_t3_id | idx_t3_id |
4       | dbatest.t4.accountid |    1 |       |
+—-+————-+——-+——+——————-+———–+———+———————-+——+——-+
2 rows in set (0.00 sec)

(5).  ref_or_null

拖欠连类型如同ref,但是补加了MySQL可以专门搜寻包含NULL值的执行。在解决子查询中时时用该联接类型的优化。

在底下的例子中,MySQL可以利用ref_or_null联接来处理ref_tables:

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

(6). index_merge

该连类型表示以了目录合并优化措施。在这种气象下,key列包含了以的目的清单,key_len包含了动的目的卓绝丰富的要因素。

例如:
mysql> explain select * from t4 where id=3952602 or
accountid=31754306 ;
+—-+————-+——-+————-+—————————-+—————————-+———+——+——+——————————————————+
| id | select_type | table | type        | possible_keys          
   | key                        | key_len | ref  | rows | Extra       
                                        |
+—-+————-+——-+————-+—————————-+—————————-+———+——+——+——————————————————+
|  1 | SIMPLE      | t4    | index_merge |
idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4 
   | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using
where |
+—-+————-+——-+————-+—————————-+—————————-+———+——+——+——————————————————+
1 row in set (0.00 sec)

(7). unique_subquery

拖欠型替换了下形式的IN子查询的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全同换子查询,效率还胜似。

(8).index_subquery

该连类型类似于unique_subquery。可以轮换IN子查询,但一味称下列形式之子查询中之非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

单纯摸给定范围之实践,使用一个目来抉择行。key列显示采用了哪位索引。key_len包含所利用索引的卓绝丰富重点因素。在该品种中ref列为NULL。

当以=、<>、>、>=、<、<=、IS
NULL、<=>、BETWEEN或者IN操作符,用常量比较主要字列时,可以以range

mysql> explain select * from t3 where id=3952602 or id=3952603 ;
+—-+————-+——-+——-+——————-+———–+———+——+——+————-+
| id | select_type | table | type  | possible_keys     | key       |
key_len | ref  | rows | Extra       |
+—-+————-+——-+——-+——————-+———–+———+——+——+————-+
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id |
4       | NULL |    2 | Using where |
+—-+————-+——-+——-+——————-+———–+———+——+——+————-+
1 row in set (0.02 sec)

(10).index

该连类型与ALL相同,除了只有索引树被扫描。这一般比ALL快,因为索引文件一般比较数据文件小。

当查问才以作为单索引一部分的排列时,MySQL可以运用该联接类型。

(11). ALL

对于每个来自于以前底阐明底行组合,进行完的阐发扫描。如果表是率先独没有号const的发明,这一般不好,并且普通在它情况下十分不同。通常可以追加又多的目录而不要采取ALL,使得行能基于前的表中的经常数值或列值被寻找出。

5.possible_keys

possible_keys列指出MySQL能运用谁索引在该表中找到实践。注意,该列完全独立于EXPLAIN输出所示之申底先后。这表示在possible_keys中之某些键实际上不能够按照生成的表次序使用。

苟该列是NULL,则尚未相关的目录。在这种情形下,可以由此检查WHERE子词看是不是它引用某些列或副索引的列来提高你的查询性能。如果是这么,创造一个宜的目录并且更用EXPLAIN检查查询

  1. key

key列显示MySQL实际决定以的键(索引)。如果没有选索引,键是NULL。要惦记强制MySQL使用还是不经意possible_keys列中的目录,在查询中应用FORCE
INDEX、USE INDEX或者IGNORE INDEX。

7.key_len

key_len列显示MySQL决定采用的键长度。如果键是NULL,则长为NULL。
应用的目的尺寸。在非损失精确性的情况下,长度逾欠越好

  1. ref

ref列显示采用谁列或常数与key一起打发明中甄选行。

  1. rows

rows列显示MySQL认为它执行查询时得检查的行数。

  1. Extra

该列包含MySQL解决查询的详细信息,下面详细.

(1).Distinct
一旦MYSQL找到了和履行相并匹配的履,就不再找了

(2).Not exists
MYSQL优化了LEFT JOIN,一旦它们找到了匹配LEFT JOIN标准的实行,

就是不再找了

(3).Range checked for each

Record(index map:#)
无找到理想的目录,因此对于自前方表中来之各级一个履组合,MYSQL检查用谁索引,并据此它们来起表中返回行。这是以索引的极度缓慢的连接有

(4).Using filesort
看看是的时刻,查询就用优化了。MYSQL需要开展额外的步子来发现什么样对回的行排序。它根据连年路及存储排序键值和匹配原则的周执之行指针来排序全部行

(5).Using index
列数据是自不过以了目录中之信息若无读取实际的行的表返回的,这出在对表的万事的请求列都是暨一个目的局部的时光

(6).Using temporary
来看是的下,查询需要优化了。这里,MYSQL需要创造一个临时表来囤积结果,这一般发生在对两样之列集进行ORDER
BY上,而无是GROUP BY上

(7).Using where
以了WHERE从句来限制哪些行将与生一样摆表匹配或者是回给用户。如果未思回到表中的全实行,并且连续类型ALL或index,这虽会发,或者是查询有题目

网站地图xml地图