EXPLAIN Join Types

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: `EXPLAIN` 输出的 `type` 列描述了表连接方式,从最优到最差包括:`system`(单行系统表)、`const`(最多一行,视为常量)、`eq_ref`(最佳连接类型,用于主键或唯一索引)、`ref`(基于索引的部分匹配)、`fulltext`(全文索引)、`ref_or_null`(包含 NULL 值的行)、`index_merge`(索引合并优化)、`unique_subquery` 和 `index_subquery`(索引查找替代子查询)、`range`(索引范围内检索)、`index`(索引扫描)、`ALL`(全表扫描,通常最差)。

EXPLAIN Output Format

image.png

EXPLAIN Join Types

EXPLAIN输出的type列描述了表是如何连接的。在JSON格式的输出中,这些是access_type属性的值。以下列表描述了连接类型,按从最佳类型到最差类型的顺序排列:

system

该表只有一行(=系统表)。这是const连接类型的一个特例。

const

该表最多有一个匹配行,在查询开始时读取。因为只有一行,所以该行列中的值可以被优化器的其余部分视为常量。const表非常快,因为它们只被读取一次。
const用于将PRIMARY KEY或UNIQUE索引的所有部分与常数值进行比较。在以下查询中,tbl_name可以用作const表:

image.png

eq_ref
对于前几张表中的每一行组合,都会从该表中读取一行。除了system和const类型之外,这是最好的连接类型。当连接使用索引的所有部分并且索引是PRIMARY KEY或UNIQUE NOT NULL索引时,使用它。
eq_ref可用于使用=运算符进行比较的索引列。比较值可以是常量,也可以是使用在此表之前读取的表中的列的表达式。在以下示例中,MySQL可以使用eq_ref连接来处理ref_table:

image.png

ref

对于前面表中的每一行组合,将从该表中读取具有匹配索引值的所有行。如果连接仅使用键的最左侧前缀,或者键不是PRIMARY key或UNIQUE索引(换句话说,如果连接无法根据键值选择单行),则使用ref。如果使用的键只匹配几行,则这是一种很好的连接类型。
ref可用于使用=或<=>运算符进行比较的索引列。在以下示例中,MySQL可以使用ref连接来处理ref_table:

image.png

fulltext
连接是使用FULLTEXT索引执行的。

ref_or_null
这种连接类型类似于ref,但MySQL会额外搜索包含NULL值的行。这种连接类型优化最常用于解决子查询。在以下示例中,MySQL可以使用ref_or_null连接来处理ref_table:

image.png

See Section 8.2.1.13, “IS NULL Optimization”.

index_merge

此连接类型表示使用了索引合并优化。在这种情况下,输出行中的键列包含所使用的索引列表,key_len包含所使用索引的最长键部分列表。有关更多信息,请参阅第8.2.1.3节“索引合并优化”。

unique_subquery

此类型替换以下形式的某些IN子查询的eq_ref:

image.png

unique_subquery只是一个索引查找函数,它完全替换了子查询以提高效率。

index_subquery
此连接类型类似于unique_subquery。它取代了IN子查询,但它适用于以下形式的子查询中的非唯一索引:

image.png

range

使用索引选择行,只检索给定范围内的行。输出行中的键列指示使用了哪个索引。key_len包含所使用的最长键部分。此类型的ref列为NULL。

当使用=、<>、>、>=、<、<=、is NULL、<=>、BETWEEN、LIKE或IN()运算符中的任何一个将键列与常量进行比较时,可以使用range:

image.png

index
索引联接类型与ALL相同,只是扫描了索引树。这有两种方式:
如果索引是查询的覆盖索引,并且可用于满足表中所需的所有数据,则只扫描索引树。在这种情况下,Extra列显示正在使用索引。仅索引扫描通常比ALL更快,因为索引的大小通常小于表数据。
使用从索引中读取的数据按索引顺序查找数据行来执行全表扫描。使用索引不会出现在“额外”列中。
当查询仅使用单个索引中的列时,MySQL可以使用此联接类型。

ALL
对前面表中的每一行组合进行全表扫描。如果表是第一个未标记为const的表,这通常是不好的,在所有其他情况下通常都是非常糟糕的。通常,您可以通过添加索引来避免ALL,这些索引允许根据早期表中的常量值或列值从表中检索行。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
数据库
解决which is not functionally dependent on columns in GROUP BY clause;...sql_mode=only_full_group_by
解决which is not functionally dependent on columns in GROUP BY clause;...sql_mode=only_full_group_by
295 0
|
SQL 数据库
SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
139 0
SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别
|
存储 .NET C#
C# LINQ 详解 From Where Select Group Into OrderBy Let Join
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. 概述     LINQ的全称是Language Integrated Query,中文译成“语言集成查询”。
2124 0
|
关系型数据库 MySQL 开发者
explain 之 select-type 和 table 介绍|学习笔记
快速学习 explain 之 select-type 和 table 介绍
817 0
|
SQL 关系型数据库 MySQL
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
468 0
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
|
SQL 关系型数据库 MySQL
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre
390 0
SQL 中 Left Join 转为 Inner Join 的实际应用
之前我写过一篇文章叫做,《SQL 中 关于Left Join 转为 Inner Join 的问题》。文章中给出的一个结论是:左关联的查询语句中,只要有 where 的过滤条件,那么该语句将被转为内关联。
3241 0
|
SQL Java
SQL 中 关于Left Join 转为 Inner Join 的问题
结论 从下面的测试结果很容易看出,左关联的查询语句中,只要有 WHERE 的过滤条件,那么该语句将被转为内关联。 一、创建表 演示使用,随便创建两张表 --班级表 CREATE TABLE T_CLASS( class_id NUMBER not null, class_name VARC.
7723 0