java获取mysql执⾏计划_在MySQL中使⽤explain查询SQL的
执⾏计划
1、什么是MySQL执⾏计划
要对执⾏计划有个⽐较好的理解,需要先对MySQL的基础结构及查询基本原理有简单的了解。
MySQL本⾝的功能架构分为三个部分,分别是 应⽤层、逻辑层、物理层,不只是MySQL ,其他⼤多数数据库产品都是按这种架构来进⾏划分的。
应⽤层,主要负责与客户端进⾏交互,建⽴链接,记住链接状态,返回数据,响应请求,这⼀层是和客户端打交道的。
逻辑层,主要负责查询处理、事务管理等其他数据库功能处理,以查询为例。
⾸先接收到查询SQL之后,数据库会⽴即分配⼀个线程对其进⾏处理,第⼀步查询处理器会对SQL查询进⾏优化,优化后会⽣成执⾏计划,然后交由计划执⾏器来执⾏。
计划执⾏器需要访问更底层的事务管理器,存储管理器来操作数据,他们各⾃的分⼯各有不同,最终通过调⽤物理层的⽂件获取到查询结构信息,将最终结果响应给应⽤层。
物理层,实际物理磁盘上存储的⽂件,主要有分⽂数据⽂件,⽇志⽂件。
通过上⾯的描述,⽣成执⾏计划是执⾏⼀条SQL必不可少的步骤,⼀条SQL性能的好坏,可以通过查看执⾏计划很直观的看出来,执⾏计划提供了各种查询类型与级别,⽅⾯我们进⾏查看以及为作为性能分析的依据。
2、如何分析执⾏计划
MySQL为我们提供了 explain 关键字来直观的查看⼀条SQL的执⾏计划。
explain显⽰了MySQL如何使⽤索引来处理select语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句。
下⾯我们使⽤ explain 做⼀个查询,如下:
mysql> explain select * from payment;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| 1 | SIMPLE | payment | NULL | ALL | NULL | NULL | NULL | NULL | 16086 | 100.00 | NULL |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
1 row in set, 1 warning (0.01 sec)
查询结构中有12列,理解每⼀列的含义,对理解执⾏计划⾄关重要,下⾯⽤⼀个表格的形式进⾏说明。
列名
说明
id
SELECT识别符,这是SELECT的查询序列号。
select_type
SELECT类型,可以为以下任何⼀种:
SIMPLE:简单SELECT(不使⽤UNION或⼦查询)
PRIMARY:最外⾯的SELECT
UNION:UNION中的第⼆个或后⾯的SELECT语句
DEPENDENT UNION:UNION中的第⼆个或后⾯的SELECT语句,取决于外⾯的查询
UNION RESULT:UNION 的结果
SUBQUERY:⼦查询中的第⼀个SELECT
DEPENDENT SUBQUERY:⼦查询中的第⼀个SELECT,取决于外⾯的查询
DERIVED:导出表的SELECT(FROM⼦句的⼦查询)
table
输出的⾏所引⽤的表
partitions
如果查询是基于分区表的话,显⽰查询将访问的分区。
type
联接类型。下⾯给出各种联接类型,按照从最佳类型到最坏类型进⾏排序:
system:表仅有⼀⾏(=系统表)。这是const联接类型的⼀个特例。
const:表最多有⼀个匹配⾏,它将在查询开始时被读取。因为仅有⼀⾏,在这⾏的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取⼀次!
eq_ref:对于每个来⾃于前⾯的表的⾏组合,从该表中读取⼀⾏。这可能是最好的联接类型,除了const类型。
ref:对于每个来⾃于前⾯的表的⾏组合,所有有匹配索引值的⾏将从这张表中读取。
ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的⾏。
index_merge:该联接类型表⽰使⽤了索引合并优化⽅法。
unique_subquery:该类型替换了下⾯形式的IN⼦查询的ref: value IN (SELECT primary_key FROM si
ngle_table WHERE some_expr) unique_subquery是⼀个索引查函数,可以完全替换⼦查询,效率更⾼。
index_subquery:该联接类型类似于unique_subquery。可以替换IN⼦查询,但只适合下列形式的⼦查询中的⾮唯⼀索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range:只检索给定范围的⾏,使⽤⼀个索引来选择⾏。
index:该联接类型与ALL相同,除了只有索引树被扫描。这通常⽐ALL快,因为索引⽂件通常⽐数据⽂件⼩。
distinct查询ALL:对于每个来⾃于先前的表的⾏组合,进⾏完整的表扫描,说明查询就需要优化了。
⼀般来说,得保证查询⾄少达到range级别,最好能达到ref。
possible_keys
指出MySQL能使⽤哪个索引在该表中到⾏
key
显⽰MySQL实际决定使⽤的键(索引)。如果没有选择索引,键是NULL。
key_len
显⽰MySQL决定使⽤的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好
ref
显⽰使⽤哪个列或常数与key⼀起从表中选择⾏。
rows
显⽰MySQL认为它执⾏查询时必须检查的⾏数。多⾏之间的数据相乘可以估算要处理的⾏数。
filtered
显⽰了通过条件过滤出的⾏数的百分⽐估计值。
Extra
该列包含MySQL解决查询的详细信息
Distinct:MySQL发现第1个匹配⾏后,停⽌为当前的⾏组合搜索更多的⾏。
Select tables optimized awayMySQL根本没有遍历表或索引就返回数据了,表⽰已经优化到不能再优化了
Not exists:MySQL能够对查询进⾏LEFT JOIN优化,发现1个匹配LEFT JOIN标准的⾏后,不再为前⾯的的⾏组合在该表内检查更多的⾏。
range checked for each record (index map: #):MySQL没有发现好的可以使⽤的索引,但发现如果来⾃前⾯的表的列值已知,可能部分索引可以使⽤。
Using filesort:MySQL需要额外的⼀次传递,以出如何按排序顺序检索⾏,说明查询就需要优化了。
Using index:从只使⽤索引树中的信息⽽不需要进⼀步搜索读取实际的⾏来检索表中的列信息。
Using temporary:为了解决查询,MySQL需要创建⼀个临时表来容纳结果,说明查询就需要优化了。
Using where:WHERE ⼦句⽤于限制哪⼀个⾏匹配下⼀个表或发送到客户。
Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index⽅式,Using index for group-by表⽰MySQL发现了⼀个索引,可以⽤来查 询GROUP BY或DISTINCT查询的所有列,⽽不要额外搜索硬盘访问实际的表。
根据上述表格,可以在执⾏计划分析上提供很好的帮助。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论