EXPLAIN Join Types

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
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,这些索引允许根据早期表中的常量值或列值从表中检索行。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
3
4
0
107
分享
相关文章
SQL SELECT TOP, LIMIT, ROWNUM 子句
SQL SELECT TOP, LIMIT, ROWNUM 子句
70 4
解决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
378 0
1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column的解决办法
1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column的解决办法
472 0
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,中文译成“语言集成查询”。
2170 0
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
564 0
MySQL - LEFT JOIN、RIGHT JOIN、INNER JOIN、CROSS JOIN、FULL JOIN
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等