前言
explain命令是查看查询优化器如何决定执行查询的主要方法。
这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的。
调用EXPLAIN
在select之前添加explain,mysql会在查询上设置一个标记,当执行查询计划时,这个标记会使其返回关于执行计划中每一步的信息,而不是执行它。
它会返回一行或多行信息,显示出执行计划中的每一部分和执行次序。
这是一个简单的explain效果:
在查询中每个表在输出只有一行,如果查询是两个表的联接,那么输出中将有两行。
别名表单算为一个表,因此,如果把一个表与自己联接,输出中也会有两行。
“表”的意义在这里相当广,可以是一个子查询,一个union结果等。
同时 explain有两个变种
EXPLAIN EXTENDED会告诉服务器“逆向编译” 执行计划为一个select语句。
可以通过紧接其后运行show warnings看到这个生成的语句,这个语句直接来自执行计划,而不是原SQL语句,到这点上已经变成一个数据结构。
大部分场景下,它都与原语句不相同,你可以检测查询偶花旗到底是如何转化语句的。
EXPLAIN EXTENDED在mysql 5.0 以上版本中可用,在5.1中增加了一个filtered列。
EXPLAIN PARTITIONS会显示查询将访问的分区,如果查询是基于分区表的话。
在mysql 5.1以上的版本中会存在。
EXPLAIN限制:
· explain根本不会告诉你触发器、存储过程或UDF会如何影响查询
· 不支持存储过程,尽管可以手动抽取查询并单独地对其进行explain操作
· 它并不会告诉你mysql在执行计划中所做的特定优化
· 它并不会显示关于查询的执行计划的所有信息
· 它并不区分具有相同名字的事物,例如,它对内存排列和临时文件都使用“filesort”,并且对于磁盘上和内存中的临时表都显示“Using temporary”
· 可能会产生误导,比如,它会对一个有着很小limit的查询显示全索引扫描(mysql 5.1的explain关于检查的行数会显示更精准的信息,但早期版本并不考虑limit)
重写非SELECT查询
mysql explain只能解释select查询,并不会对存储程序调用和insert、update、delete或其他语句做解释。然而,你可以重写某些非select查询以利用explain。为了达到这个目的,只需要将该语句转化成一个等价的访问所有相同列的select,任何体积的列都必须在select列表,关联子句,或者where子句中。
新闻热点
疑难解答