MySQL执行计划详解
MySQL执行计划(Execution Plan)是指MySQL在执行查询语句时生成的一份计划,通过该计划可以了解MySQL是如何执行查询,包括哪些表被查询、表之间的连接方式、数据的读取方式、使用的索引等,从而帮助我们对查询语句进行调优,提高查询性能。
执行计划的生成
MySQL在执行查询语句时,会经历以下几个步骤生成执行计划:
- 语法分析:MySQL会进行语法分析,验证查询语句的正确性。
- 查询优化器:MySQL会使用查询优化器优化查询语句,生成多种执行方案,并选择代价最小的一种方案作为执行计划。
- 执行计划生成器:MySQL会根据选择的执行方案,生成执行计划。
执行计划的查看
我们可以通过EXPLAIN
命令查看执行计划,以下是该命令的基本格式:
EXPLAIN SELECT * FROM table1 WHERE id=1;
执行该命令后,MySQL会返回一张表格,其中包含了查询的详细信息,如下:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | table1 | NULL | ref | PRIMARY | PRIMARY | 4 | const | 1 | 100 | Using index |
- id:查询中每个SELECT子句的标识符,对于简单的SELECT查询,表示查询语句中的第N个表;
- select_type:查询的类型,包括SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION、UNION RESULT等;
- table:查询中所涉及的表;
- partitions:匹配的分区数目(MySQL 5.1以上版本支持);
- type:访问类型,包括ALL、index、range、ref、eq_ref、const、system、NULL、possible_keys等;
- possible_keys:可能使用的索引;
- key: 实际使用的索引;
- key_len:所使用的索引的长度;
- ref:索引的参考列;
- rows:扫描表的行数;
- filtered:表的过滤程度(0~100);
- extra:附加信息,包括Using filesort、Using temporary、Using index等。
示例一
EXPLAIN SELECT * FROM orders WHERE order_date BETWEEN '2020/01/01' AND '2020/12/31';
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | orders | NULL | range | order_date | order_date | 4 | NULL | 918 | 100.00 | Using where |
该查询使用了range访问类型,可能使用了order_date索引,并且真正使用了order_date索引,过滤了918行。
示例二
EXPLAIN SELECT a.*, b.* FROM orders a JOIN order_items b ON a.order_id = b.order_id WHERE a.order_date BETWEEN '2020/01/01' AND '2020/12/31' AND b.quantity > 10;
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | b | NULL | ref | PRIMARY,order_id | order_id | 4 | NULL | 183 | 100 | Using index condition; Using where; Using temporary |
1 | SIMPLE | a | NULL | eq_ref | PRIMARY,order_date | PRIMARY | 4 | database.b.order_id | 1 | 100 | Using where |
该查询使用了Using temporary来进行连接操作,其中b表使用了索引order_id进行过滤,因为包含了查询的WHERE条件中的order_id列。a表直接使用PRIMARY索引,因为建立了order_id和PRIMARY索引的关系;同时根据查询的WHERE条件,也使用了order_date索引。最后两个表进行了嵌套循环联接(eq_ref),使用了PRIMARY键和order_id连接;两个查询都使用了WHERE条件筛选。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL执行计划详解 - Python技术站