怎么查看mysql计划执行情况(详解 MySQL 执行计划)
怎么查看mysql计划执行情况
详解 MySQL 执行计划EXPLAIN语句提供有关MySQL如何执行语句的信息。EXPLAIN与SELECT,DELETE,INSERT,REPLACE和UPDATE语句一起使用。
EXPLAIN为SELECT语句中使用的每个表返回一行信息。它按照MySQL在处理语句时读取它们的顺序列出了输出中的表。 MySQL使用嵌套循环连接方法解析所有连接。这意味着MySQL从第一个表中读取一行,然后在第二个表,第三个表中找到匹配的行,依此类推。处理完所有表后,MySQL输出所选列,并通过表列表回溯,直到找到一个表,其中有更多匹配的行。从这个表中读取下一行,然后继续处理下一个表。
1. EXPLAIN 输出列
说下几个关键的列:
- type :连接类型
- possible_keys :可选的索引
- key :实际执行时使用的索引
- ref :ref列显示将哪些列或常量与前面key列中显示的命名的索引进行比较以从表中选择行
- rows :rows列表示MySQL认为执行查询必须检查的行数
2. 连接类型
连接类型,顺序从最好到最差,依次是:
system
表只有一行。这是const join类型的特例。
const
表最多有一个匹配行,在查询开始时读取。因为只有一行,所以这一行中的列的值可以被优化器的其余部分视为常量。const表非常快,因为它们只被读取一次。
当你用PRIMARY KEY或UNIQUE索引的所有部分与常量值进行比较时,将使用const。
例如,下面的表tbl_name可以被当做const表:
|
SELECT * FROM tbl_name WHERE primary_key=1; SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2; |
eq_ref
对于前表中的每一行组合,从这个表中读取一行。除了system和const类型,这是可能的最好的联接类型。当一个索引的所有部分都被联接使用并且索引是PRIMARY KEY或UNIQUE NOT NULL索引时,使用它。
eq_ref可以用于使用=操作符进行比较的索引列。比较值可以是一个常量,也可以是使用在此表之前读取的表中的列的表达式。
例如,下面的例子中MySQL可以使用eq_ref连接来处理ref_table:
|
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table. column ; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table. column AND ref_table.key_column_part2=1; |
ref
对于前表中的行的每种组合,将从该表中读取具有匹配索引值的所有行。如果联接仅使用key的最左前缀,或者如果key不是PRIMARY KEY或UNIQUE索引(换句话说,如果联接无法基于key值选择单个行),则使用ref。如果使用的key仅匹配几行,则这是一种很好的联接类型。
ref可用于使用=或<=>运算符进行比较的索引列。
例如,下面的例子中,MySQL可以用ref连接来处理ref_table:
|
SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table. column ; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table. column AND ref_table.key_column_part2=1; |
fulltext
使用FULLTEXT索引执行连接
ref_or_null
这种连接类型类似于ref,但是MySQL会额外搜索包含NULL值的行。此联接类型优化最常用于解析子查询。
例如,下面的例子中,MYSQL可以使用ref_or_null来处理ref_table:
|
SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL ; |
index_merge
这种连接类型表明使用了索引合并优化。在这种情况下,输出行中的key列包含使用的索引列表,而key_len包含所使用索引的最长key部分列表。
unique_subquery
此类型将eq_ref替换为以下形式的某些IN子查询:
|
value IN ( SELECT primary_key FROM single_table WHERE some_expr) |
index_subquery
与unique_subquery类似,它代替了IN子查询,但适用于以下形式的子查询中的非唯一索引:
|
value IN ( SELECT key_column FROM single_table WHERE some_expr) |
range
只检索给定范围内的行,并使用索引来选择行。输出行中的key列指示使用了哪个索引。key_len包含所使用的最长的key部分。对于这种类型,ref列为NULL。
使用=,<>,>,> =,<,<=,IS NULL,<=>,BETWEEN,LIKE或IN()运算符将key列与常量进行比较时,可以使用range:
|
SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name WHERE key_column IN (10,20,30); SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30); |
index
index连接类型与all是一样的,区别在于index连接类型扫描的时候索引树。通常,只发生在以下两种情况:
- 如果索引是查询的覆盖索引,并且可用于满足表中所需的所有数据,则仅扫描索引树。在这种情况下,“Extra”列显示“Using index”。仅索引扫描通常比ALL快,因为索引的大小通常小于表数据。
- 使用从索引读取数据以按索引顺序查找数据行来执行全表扫描。“Uses index”不会出现在Extra列中。
ALL
对前表的行的每个组合进行全表扫描。如果该表是未标记为const的第一个表,则通常不好,并且在所有其他情况下通常非常糟糕。通常,可以通过添加索引来避免ALL,这些索引允许基于早期表中的常量值或列值从表中检索行。
3. Extra列
关于Extra列的输出,只说几个常见的:
Using filesort
MySQL必须做一次额外操作,以找出如何按排序顺序检索行。排序是通过根据联接类型遍历所有行并存储与WHERE子句匹配的所有行的排序key和指向该行的指针来完成的。然后对key进行排序,并按排序顺序检索行。
Using index
仅使用索引树中的信息从表中检索列信息,而不需要执行额外的查找来读取实际行。当查询只使用属于单个索引的列时,可以使用此策略。
Using temporary
为了解析查询,MySQL需要创建一个临时表来保存结果。通常,如果查询包含以不同方式展示列的GROUP BY和ORDER BY子句,则会发生这种情况。
Using where
WHERE子句用于限制哪些行匹配下一个表或发送给客户端。除非你打算从表中获取或检查所有行,否则如果额外的值没有使用where,并且表连接类型是all或index,则查询中可能出现错误。
4. 优化ORDER BY
在某些情况下,MySQL可能会使用一个索引来满足ORDER BY子句,从而避免执行filesort操作所涉及的额外排序。
假设在(key_part1, key_part2)上有一个索引,下面的查询可以使用索引来解析ORDER BY部分。优化器是否真的这样做,取决于如果还必须读取索引之外的时,读取索引是否比表扫描更有效。
|
SELECT * FROM t1 ORDER BY key_part1, key_part2; |
上面的语句,查询使用SELECT *,这可能会选择比key_part1和key_part2更多的列。在这种情况下,扫描整个索引并查找表行以查找索引中未包含的列可能比扫描表并排序结果要昂贵。如果是这样,则优化器不太可能使用索引。如果SELECT *仅选择索引列,则使用索引并避免排序。
下面这个查询中,key_part1是常量,因此通过索引访问的所有行都按key_part2顺序排列,并且如果WHERE子句的选择性足以使索引范围扫描比表扫描便宜,则在(key_part1,key_part2)上的索引可以避免排序:
|
SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2; |
以上就是详解 MySQL 执行计划的详细内容,更多关于MySQL 执行计划的资料请关注开心学习网其它相关文章!
原文链接:https://www.cnblogs.com/cjsblog/p/14185582.html
- mysql查询语法总结(MySQL全面瓦解之查询的过滤条件详解)
- mysql为什么优选innodb(如何区分MySQL的innodb_flush_log_at_trx_commit和sync_binlog)
- mysql慢日志查询作用(MySQL 慢查询日志的开启与配置)
- mysql索引原理和优化(Mysql 索引该如何设计与优化)
- mysql8使用技巧(一篇学会MySQL 8.0 ROLE管理)
- python mysql配置(详解python校验SQL脚本命名规则)
- mysql中mergeinto的用法(MySQL中exists、in及any的基本用法)
- mysql主从同步复制原理(MYSQL数据库GTID实现主从复制实现超级方便)
- phpstudymysql数据库启动不了(phpstudy mysql启动不了的解决方法)
- mysql数据库导入错误怎么处理(MySQL数据库导入导出数据之报错解答实例讲解)
- navicatformysql使用视图(Navicat for MySQL的使用教程详解)
- mysql server安装图解教程(mysql容器之间的replication配置实例详解)
- thinkphp5.1手动连接mysql数据库(thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例)
- mysql为啥使用b+树(MySQL用B+树作为索引结构有什么好处)
- mysql带log的版本(聊聊MYSQL中Redo Log是什么?)
- mysql如何给一个表批量添加字段(mysql从一张表查询批量数据并插入到另一表中的完整实例)
- 十二星座爱情支配欲指数(十二星座爱情支配欲指数)
- 虐待儿童是发泄支配欲的愚蠢行为(虐待儿童是发泄支配欲的愚蠢行为)
- 你或许不知道你隐藏的支配欲望(你或许不知道你隐藏的支配欲望)
- 把宽体丰田86卖了,换成7.5代高尔夫GTI玩起姿态与性能并存的改装(把宽体丰田86卖了)
- 大众推出了第五代高尔夫GT(大众推出了第五代高尔夫GT)
- 换代在即,现在是抄底 7.5代 高尔夫的最佳时机吗(换代在即现在是抄底)
热门推荐
- python ip代理池(Python 实现域名解析为ip的方法)
- kubernetes的安全机制(浅析kubernetes的控制器和标签)
- Ext.slider控件的用法
- oracle日期函数
- sublime text 安装package control,方便其它插件安装
- dedecms标签插入时间(dedecms修改按tag标签显示全站相关内容的方法)
- set statistics time on的理解
- ssl服务器搭建的步骤(windows apache环境下部署SSL证书让网站支持https的配置方法)
- ASP.NET压力测试
- 服务器启动nginx服务的命令(Nginx服务器添加Systemd自定义服务过程解析)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9