您的位置:首页 > 数据库 > MySQL

MySQL(Explain)

2017-01-07 00:00 495 查看
摘要: MySQL Explain详解

explain table_name
or
explain select_string
or
explain extended select_string

EXPLAIN:
1)你可以知道什么时候必须为表加入索引以得到一个使用索引找到记录的更快的SELECT。
2)你可以知道也能知道优化器是否以一个最佳次序联结表。为了强制优化器对一个SELECT语句使用一个特定联结次序,增加一个
3)EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
4)EXPLAIN不考虑各种Cache
5)EXPLAIN不能显示MySQL在执行查询时所作的优化工作
6)部分统计信息是估算的,并非精确值
7)EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划

explain PendingPriceStatistics.4conscn_deal;
+----------------+-------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+-------------------+-------+
| insert_db_time | timestamp | NO | | CURRENT_TIMESTAMP | |
| price | int(1) | NO | PRI | 0 | |
| total | int(1) | YES | | NULL | |
| ename | int(1) | YES | | NULL | |
| ename-dealer | int(1) | YES | | NULL | |
| am | int(1) | YES | | NULL | |
| am-dealer | int(1) | YES | | NULL | |
| range | varchar(50) | YES | | NULL | |
+----------------+-------------+------+-----+-------------------+-------+

explain select * from PendingPriceStatistics.4conscn_deal where price=8777 ;
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | 4conscn_deal | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+-------+

explain extended select * from PendingPriceStatistics.4conscn_deal where price=8777 ;
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | 4conscn_deal | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
+----+-------------+--------------+-------+---------------+---------+---------+-------+------+----------+-------+

Column含义详解
id查询序号
select_type查询类型主要是区别普通查询和联合查询、子查询之类的复杂查询
table表名输出的行所引用的表
partitions匹配的分区version 5.6 没有
typejoin类型联合查询所使用的类型
prossible_keys可能会选择的索引结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref
key实际选择的索引指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname),FORCE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引
key_len索引的长度显示MySQL决定使用的键长度。如果键是NULL,长度就是NULL。文档提示特别注意这个值可以得出一个多重主键里mysql实际使用了哪一部分。在不损失精确性的情况下,长度越短越好。
ref与索引作比较的列显示使用哪个列或常数与key一起从表中选择行。
rows要检索的行数(估算值)这个数表示mysql要遍历多少数据才能找到,在innodb上是不准确的
filtered查询条件过滤的行数的百分比指返回结果的行占需要读到的行(rows列的值)的百分比
Extra额外信息关于MYSQL如何解析查询的额外信息。坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢。
using index ,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
where used,就是使用上了where限制。
impossible where 表示用不着where,一般就是没查出来啥。
using temporary,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
Using filesort ,MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
select-type:
1) SIMPLE:简单的SELECT,不使用UNION或者子查询。
2) PRIMARY:最外层SELECT。
3) UNION:第二层,在SELECT之后使用了UNION。
4) DEPENDENT UNION:UNION语句中的第二个SELECT,依赖于外部子查询。
5) UNION RESULT:UNION的结果。
6) SUBQUERY:子查询中的第一个SELECT。
7) DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询。
8) DERIVED:导出表的SELECT(FROM子句的子查询)

type:
1) system:表仅有一行(=系统表)。这是const联结类型的一个特例。
2) const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
3) eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。
4) ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。ref可以用于使用=或<=>操作符的带索引的列。
5) ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
6) index_merge:该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
7) unique_subquery:该类型替换了下面形式的IN子查询的ref:
value in (select primary_key from single_table where some_expr)
unque_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
8) index_subquery:该联结类型类似于unique_subquery。可以替换in子查询,但只适合下列形式的子查询中的非唯一索引:
value in (select key_column from single_table where som_expr)
9) range:只检索给定范围的行,使用一个索引来选择行。Key列显示使用了哪个索引。Key_len包含使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range。
10) index:该联结类型与ALL相同,除了只有索引树被扫描。通常比ALL快,因为索引文件通常比数据文件小。当查询中索引只作为一部分时,mysql可以使用该联结类型。
11) ALL:对于每个来自先前的表的行组合,进行完整的表扫描。如果表是第一个没有标记const的表,这通常不好,并且很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或者列值被检索出。

extra:
1) Distinct:一旦mysql找到了与行相联合匹配的行,就不再搜索了。
2) Not exists:mysql又花了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了。
3) Range checked for each:没有找到理想的索引,因此对于从前面表中来的每一个行组合,mysql检查使用哪个索引,并且它从表中返回行。这是使用索引的最慢的联结之一。
4) Using filesort:看到这个的时候查询就需要优化了。Mysql需要进行额外的步骤来发现如何对返回的行进行排序。它根据联结类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。
5) Using index condition:列数据是从仅仅使用了索引中的信息而没有读取实际的行的表返回的,这发生在队标的全部请求都是同一个索引的部分的时候。
6) Using temporary:看到这个的时候,查询就需要优化了。这里mysql需要创建一个临时表来存储结果,这通常发生在对不同的列集进行order by上,而不是GROUP by
7) Using where:试用了where从句来显示哪些行将于下一张表匹配或者返回给用户。如果不想返回表中的全部行,并且连接类型为ALL或index,就会发生,或者是查询有问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  MySQL Explain