MySQL EXPLAIN 语句

MySQL EXPLAIN子句相关转载
该博客为转载内容,原文链接为https://www.cnblogs.com/Wayou/p/mysql_explain_clause.html ,涉及数据库相关知识。

对于 MySQL 在执行时来说,EXPLAIN 功能上与 DESCRIBE 一样。实际运用中,后者多用来获取表的信息,而前者多用于展示 MySQL 会如何执行 SQL 语句(Obtaining Execution Plan Information)。

DESCRIBE 实质上是 SHOW COLUMNS 语句的缩略形式。

  • EXPLAIN 可作用于这些 SQL 关键词:SELECT, DELETE, INSERT, REPLACE 以及 UPDATE。
  • 当作用于可解释性的语句(explainable statement)时,其展示相应 SQL 语句被优化后的执行计划(execution plan),也就是 MySQL 会如何处理该 SQL 查询语句,比如有 JOIN 语句时多表是怎样结合,以怎样的顺序结合。
  • 当作用于 FOR CONNECTION connection_id 而不是可解释性语句时,其展示的是该连接的执行计划。
  • 涉及到对分区表的查询时,EXPLAIN 就十分有用了。

通过 EXPLAIN 你能看出在哪里添加索引以优化加速查询语句,也可以查看联表时是否以最佳顺序进行的。

EXPLAIN 的输出中,为每张参与查询的表生成一行结果,顺序则是按 MySQL 读取这些且的顺序。MySQL 进行 JOIN 操作时,实际是是通过嵌套循环完成的,即先读取第一张表的一条记录,再去第二张表中寻找匹配的记录,再去第三张表中匹配,以此类推。

Wrokbench 中查看执行计划

MySQL 的 GUI 工具 Workbench 提供了可视化的途径查看执行计划,这对于性能分析很有用。

MySQL Workbench 中执行计划的可视化展示

MySQL Workbench 中执行计划的可视化展示

EXPLAIN 输出表格中的含义

列名JSON 中的列名含义
idselect_idSELECT 标识
select_typeN/ASELECT 类型
tabletable_name构造该行输出的表名
partitionspartitions匹配到的分区表
typeaccess_typeJOIN 类型
possible_keyspossible_keys可选的索引
keykey真实选中的索引
key_lenkey_length被选中的键的长度
refref用于和索引进行对比的列
rowsrows预估用于查询的记录数
filteredfiltered被查询条件过滤掉的记录数百分比
ExtraN/A额外的其他信息

来自 MySQL Reference Manual 中关于 EXPLAIN 输出的表格

其中 JSON 列表是将该输出导出为 JSON 格式时使用的列名。

其中 select_type SELECT 类型,所有可能的值见下表:

select_type ValueJSON NameMeaning
SIMPLENone普通类型的 SELECT,没有 UNION 及子查询
PRIMARYNone最外层的 SELECT
UNIONNone配合 UNION 使用时第二个及后面的 SELECT
DEPENDENT UNIONdependent (true)配合 UNION 使用时第二个及后面的 SELECT,因外层的查询而有差异
UNION RESULTunion_resultUNION 返回的结果
SUBQUERYNone子查询中第一个 SELECT
DEPENDENT SUBQUERYdependent (true)子查询中第一个 SELECT,因外层查询而异
DERIVEDNone衍生表
DEPENDENT DERIVEDdependent (true)依赖于其他表的衍生表
MATERIALIZEDmaterialized_from_subquery物化的子查询
UNCACHEABLE SUBQUERYcacheable (false)无法缓存的子查询,对于第一行必需重新执行
UNCACHEABLE UNIONcacheable (false)不可缓存的子查询里 UNION 中第二个及往后的 SELECT

type JOIN 类型描述表是如何被联接的,其可能的值有以下这些,排序由最优到最次:

  • system:表中只有一条记录,属于 const JOIN 类型的一个特例。
  • const:表中至多只有一条匹配的记录。因为只有一条,所以取出的列值可当作常量被优化,查询速度最快。当主键( PRIMARY KEY)或唯一性索引(UNIQUE index)与常量进行比较时,会使用此类型。
SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name
  WHERE primary_key_part1=1 AND primary_key_part2=2;
  • eq_ref:对于前面每个表中记录的组合,都从这个表里读取一条记录。该类型可用于对索引列使用 = 操作符进行比较时。
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:对于前面每个表中记录的组合,从该表读取所有所有匹配到的索引记录。ref 用于 JOIN 使用使用非主键或唯一索引列时,或只使用键的前缀的场景。
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:JOIN 使用的是 FULLTEXT 类型的索引
  • ref_or_null:类似 ref,但会对 NULL 值做额外的查询。这种类型的 JOIN 优化常用于子查询,以下的示例 MySQL 全会使用 ref_or_null 联表来处理 ref_table :
SELECT * FROM ref_table
  WHERE key_column=expr OR key_column IS NULL;
value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range:只返回范围内的记录。
  • index:同 ALL 类型,但只使用索引来搜索。
  • ALL:查询时进行全表扫描。

相关资源

转载于:https://www.cnblogs.com/Wayou/p/mysql_explain_clause.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值