7.2.1 EXPLAIN 语法(得到 SELECT 的相关信息) EXPLAIN tbl_name 或者: EXPLAIN SELECT select_options EXPLAIN 语句可以被当作 DESCRIBE 的同义词来用,也可以用来获取一个MySQL要执行的 SELECT 语句的相关信息。 EXPLAIN tbl_name 语法和 DESCRIBE tbl_na
7.2.1 EXPLAIN
语法(得到SELECT
的相关信息)
EXPLAIN <var>tbl_name</var>
或者:
EXPLAIN SELECT <var>select_options</var>
EXPLAIN
语句可以被当作 DESCRIBE
的同义词来用,也可以用来获取一个MySQL要执行的 SELECT
语句的相关信息。
-
EXPLAIN tbl_name
语法和DESCRIBE tbl_name
或SHOW COLUMNS FROM tbl_name
一样。 - 当在一个
SELECT
语句前使用关键字EXPLAIN
时,MYSQL会解释了即将如何运行该SELECT
语句,它显示了表如何连接、连接的顺序等信息。
本章节主要讲述了第二种 EXPLAIN
用法。
在 EXPLAIN
的帮助下,您就知道什么时候该给表添加索引,以使用索引来查找记录从而让 SELECT
运行更快。
如果由于不恰当使用索引而引起一些问题的话,可以运行 ANALYZE TABLE
来更新该表的统计信息,例如键的基数,它能帮您在优化方面做出更好的选择。详情请看”14.5.2.1 ANALYZE TABLE
Syntax”。
您还可以查看优化程序是否以最佳的顺序来连接数据表。为了让优化程序按照 SELECT
语句中的表名的顺序做连接,可以在查询的开始使用 SELECT STRAIGHT_JOIN
而不只是 SELECT
。
EXPLAIN
返回了一行记录,它包括了 SELECT
语句中用到的各个表的信息。这些表在结果中按照MySQL即将执行的查询中读取的顺序列出来。MySQL用一次扫描多次连接(single-sweep, multi-join) 的方法来解决连接。这意味着MySQL从第一个表中读取一条记录,然后在第二个表中查找到对应的记录,然后在第三个表中查找,依次类推。当所有的表都扫描 完了,它输出选择的字段并且回溯所有的表,直到找不到为止,因为有的表中可能有多条匹配的记录下一条记录将从该表读取,再从下一个表开始继续处理。
在MySQL version 4.1中,EXPLAIN
输出的结果格式改变了,使得它更适合例如 UNION
语句、子查询以及派生表的结构。更令人注意的是,它新增了2个字段: id
和 select_type
。当你使用早于MySQL 4.1的版本就看不到这些字段了。
EXPLAIN
结果的每行记录显示了每个表的相关信息,每行记录都包含以下几个字段:
id
- 本次
SELECT
的标识符。在查询中每个SELECT
都有一个顺序的数值。 select_type
-
SELECT
的类型,可能会有以下几种: -
SIMPLE
- 简单的
SELECT
(没有使用UNION
或子查询) PRIMARY
- 最外层的
SELECT
。 UNION
- 第二层,在
SELECT
之后使用了UNION
。 DEPENDENT UNION
-
UNION
语句中的第二个SELECT
,依赖于外部子查询 SUBQUERY
- 子查询中的第一个
SELECT
DEPENDENT SUBQUERY
- 子查询中的第一个
SUBQUERY
依赖于外部的子查询 DERIVED
- 派生表
SELECT
(FROM
子句中的子查询)
table
- 记录查询引用的表。
typ本文来源gao($daima.com搞@代@#码$网e
- 表连接类型。以下列出了各种不同类型的表连接,依次是从最好的到最差的:
system
- 表只有一行记录(等于系统表)。这是
const
表连接类型的一个特例。 const
- 表中最多只有一行匹配的记录,它在查询一开始的时候就会被读取出来。由于只有一行记录,在余下的优化程序里该行记录的字段值可以被当作是一个恒定值。
const
表查询起来非常快,因为只要读取一次!const
用于在和PRIMARY KEY
或UNIQUE
索引中有固定值比较的情形。下面的几个查询中,tbl_name 就是 const 表了:SELECT * FROM <var>tbl_name</var> WHERE <var>primary_key</var>=1;<br />SELECT * FROM <var>tbl_name</var><br />WHERE <var>primary_key_part1</var>=1 AND <var>primary_key_part2</var>=2;<br />
eq_ref
- 从该表中会有一行记录被读取出来以和从前一个表中读取出来的记录做联合。与
const
类型不同的是,这是最好的连接类型。它用在索引所有部分都用于做连接并且这个索引是一个PRIMARY KEY
或UNIQUE
类型。eq_ref
可以用于在进行”=”做比较时检索字段。比较的值可以是固定值或者是表达式,表达示中可以使用表里的字段,它们在读表之前已经准备好了。以下的几个例子中,MySQL使用了eq_ref
连接来处理 ref_table: -
SELECT * FROM <var>ref_table</var>,<var>other_table</var><br />WHERE <var>ref_table</var>.<var>key_column</var>=<var>other_table</var>.<var>column</var>;<br />SELECT * FROM <var>ref_table</var>,<var>other_table</var><br />WHERE <var>ref_table</var>.<var>key_column_part1</var>=<var>other_table</var>.<var>column</var><br />AND <var>ref_table</var>.<var>key_column_part2</var>=1;<br />
ref
- 该表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录作联合。
ref
用于连接程序使用键的最左前缀或者是该键不是PRIMARY KEY
或UNIQUE
索引(换句话说,就是连接程序无法根据键值只取得一条记录)的情况。当根据键值只查询到少数几条匹配的记录时,这就是一个不错的连接类型。ref
还可以用于检索字段使用=
操作符来比较的时候。以下的几个例子中,MySQL将使用ref
来处理 ref_table:SELECT * FROM <var>ref_table</var> WHERE <var>key_column</var>=<var>expr</var>;<br />SELECT * FROM <var>ref_table</var>,<var>other_table</var><br />WHERE <var>ref_table</var>.<var>key_column</var>=<var>other_table</var>.<var>column</var>;<br />SELECT * FROM <var>ref_table</var>,<var>other_table</var><br />WHERE <var>ref_table</var>.<var>key_column_part1</var>=<var>other_table</var>.<var>column</var><br />AND <var>ref_table</var>.<var>key_column_part2</var>=1;<br />
ref_or_null
- 这种连接类型类似
ref
,不同的是MySQL会在检索的时候额外的搜索包含NULL
值的记录。这种连接类型的优化是从MySQL 4.1.1开始的,它经常用于子查询。在以下的例子中,MySQL使用ref_or_null
类型来处理 ref_table:SELECT * FROM <var>ref_table</var><br />WHERE <var>key_column</var>=<var>expr</var> OR <var>key_column</var> IS NULL;<br />