MySQL中SQL执行计划,你理解了吗

首先我们来看一下什么是执行计划:执行计划就是解释select语句如何在数据库执行的、相关表是怎么连接、连接的次序、有哪些索引和索引使用情况、每个表的扫描数据量等等。简单来说,就是通过数据来分析select语句的执行情况;怎么查看执行计划:查看执行需要用到关键字EXPLAIN,将EXPLAIN放在SQL语句的前面(EXPLAIN[EXTENDED]SELECTselect_options),如下图:从上图可以看出,通过执行计划展示了表格数据,这个表格有id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、extra等字段的信息,这些字段分别表示什么意思呢?下面具体介绍下:1、id执行计划的id是select查询的序列号,标识执行顺序。注意有两种情况,具体如下:1)、当id相同时,执行顺序从上到下执行。左外连接,先执行左边后执行右边(例如:select*fromuseruleftjoincustom_ordercoonu.id=co.creater会先执行user表后执行custom_order),在执行计划中,user表应该在上面,custom_order在下面,如下图:右外连接,先执行右边后执行左边(例如:select*fromuserurightjoincustom_ordercoonu.id=co.creater会先执行custom_order表后执行user表),在执行计划中,custom_order表应该在上面,user在下面,如下图:从上面的执行结果来看,和预计的一样。2)、当id不相同时,id越大越先执行。例如:select*fromuserwhereid=(selectcreaterfromcustom_orderwhereid=1),这个语句中的子查询会比主查询会先执行。那在explainselect*fromuserwhereid=(selectcreaterfromcustom_orderwhereid=1)中custom_order的id应该是2,user的id应该是1,实际是不是这样呢,如下图:从结果中可以知道,执行结果和预计的一样;2、select_type执行计划的select_type是select语句的类型,用于区分各种查询;具体类型有以下几种:1)、SIMPLE简单的select语句,不使用union或子查询。如下图:2)、PRIMARY最外层的select语句。如下图3)、UNIONunion中的第二个或后面的select语句。如下图4)、DEPENDENTUNIONunion中的第二个或后面的select语句,取决于外面的查询。如下图5)、UNIONRESULTunion的结果。如下图6)、SUBQUERY子查询的第一个select语句。如下图7)、DEPENDENTSUBQUERY子查询中的第一个select语句,取决于外面的查询。如下图8)、DERIVED衍生表的select语句(在from列表中包含的子查询)。如下图3、table语句查询中所涉及到的表。如下图:4、partitions查询涉及到的分区别。如下图:5、typeSQL语句的连接类型。具体个连接类型如下:(按照从效率高的类型到效率低的类型进行排序)1)、system表仅有一行(等于系统表)。这是const连接类型的一种特例。2)、const表最多有一个匹配行,它将在查询开始时被读取,常用于主键或唯一索引的定值查询。因为匹配行只有一行,所以查询速度很快。如下图(id是主键):3)、eq_ref唯一性索引扫描,对于前表的每一行,表中只有一行与之相匹配或者没有能匹配。常见于主键或唯一索引扫描。是除const类型和system类型外最快的类型。如下图:4)、ref非唯一性索引扫描,对于前表的每一行,表中可存在多个与之相匹配的行。如下图:5)、ref_or_null和ref类型一样,但是添加了mysql可以专门搜索包含NULL值的行。如下图:6)、index_merge标识使用了索引合并优化方法。如下图:7)、unique_subquery一个索引查找函数,可以完全替换子查询,效率更高。8)、index_sugquery类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引。9)、range只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、、、=、、=、ISNULL、=、BETWEEN或者IN操作符,用常量比较关键字列时。如下图:10)、index扫描索引树。如果索引是复合索引,并且复合索引列满足select所需的所有数据,则仅扫描索引树,不需要回表。如下图:11)、ALL扫描全表。这是最差的情况,没有索引,进行完整的表扫描。如下图:6、possible_keys语句中能使用索引有哪些。如下图:7、key该语句执行的时候是使用的哪条索引。如下图:8、key_len该语句执行时使用的索引长度(字节数)。如下图:9、ref该表的索引字段关联了哪张表的哪个字段。如下图:10、rows该语句执行时需要读取行数,数越小越好。如下图:11、filtered该语句返回结果的行数占读取行数的百分比,值越大越好。如下图:12、extra十分重要的额外信息。常见的如下:1)、DistinctMySQL发现第一个匹配的行后,停止为当前索引搜索更多的行。2)、NotexistsMySQL能够对查询进行LEFTJOIN优化,发现1个匹配LEFTJOIN标准的行后,不再为前面的索引在该表内检查更多的行。如下图:3)、UsingfilesortMySQL对数据使用一个外部的文件内容进行了排序,而不是按照表内的索引进行排序读取。如下图:4)、Usingindex仅使用索引树中的信息从表中检索列信息,而不必另外寻找读取实际行,即不需要回表。如下图:5)、Usingtemporyary在查询时,MySQL需要创建一个临时表来保存结果。常出现使用GROUPBY和ORDERBY子句时。如下图:6)、Usingwhere在查找使用索引的情况下,需要回表去查询所需的数据,后再用WHERE子句完成结果过滤,通常出现这种情况的话就需要添加合适的索引来做优化了。如下图:7)、Usingjoinbuffer连接中的表分成几部分读入连接缓冲区,然后从缓冲区中使用它们的行来与当前表执行连接。如下图:这次的内容就到这里,欢迎大家在评论区评论!


转载请注明:http://www.aierlanlan.com/cyrz/8359.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了