mysql EXPLAIN Join Types 手册解释 及数据实操
第一部分:名称解释
文档地址
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
EXPLAIN Join Types:
The type column of EXPLAIN output describes how tables are joined. In JSON-formatted output,
these are found as values of the access_type property. The following list describes the join types,
ordered from the best type to the worst: Explains 列描述了表与表之间是如何连接的,在JSON格式的输出中,这些被发现为access_type属性的值。下面对于join 的不同类型描述列表中,分布从最好到最坏
system
The table has only one row (= system table). This is a special case of the const join type.
表中只有一列数据,是const 连接类型中的一个特殊列子
const
The table has at most one matching row, which is read at the start of the query. Because there is only one row,
values from the column in this row can be regarded as constants by the rest of the optimizer. const tables are
very fast because they are read only once.
表中至多有一条可以被匹配到,在查询最开始的时候会被读取。由于只有一条数据,因此该行中的列值会被剩下的优化器认定为常量值。常量值由于只需
要读取一次,因此被认为是非常快速的。
const is used when you compare all parts of a PRIMARY KEY or UNIQUE index to constant values. In the following queries,
tbl_name can be used as a const table: 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
One row is read from this table for each combination of rows from the previous tables. Other than the system and const
types, this is the best possible join type. It is used when all parts of an index are used by the join and the index is
a PRIMARY KEY or UNIQUE NOT NULL index.
当前面的表join到当前表的时候,每一个join 当前表只会有一条记录被连接到。除了system和const类型,这是最好的连接类型。当索引整体被使用到并且索引
是主键或者唯一索引的时候,会出现这种类型的连接
eq_ref can be used for indexed columns that are compared using the = operator. The comparison value can be a constant or
an expression that uses columns from tables that are read before this table. In the following examples, MySQL can use an eq_ref
join to process ref_table:
当比较是等于号的时候,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
All rows with matching index values are read from this table for each combination of rows from the previous tables.
ref is used if the join uses only a leftmost prefix of the key or if the key is not a PRIMARY KEY or UNIQUE index
(in other words, if the join cannot select a single row based on the key value). If the key that is used matches only
a few rows, this is a good join type.
所有具有匹配索引值的行都从这个表中读取,用于以前表中的每个行的组合。 如果连接仅使用键的最左边的前缀,或者键不是PRIMARY KEY或UNIQUE索引(换句话说,
如果连接不能根据键值选择单个行),则使用ref。如果使用的键只匹配几行,这是一个很好的连接类型。
SELECT*FROMref_tableWHEREkey_column=expr;SELECT*FROMref_table,other_tableWHEREref_table.key_column=other_table.column;SELECT*FROMref_table,other_tableWHEREref_table.key_column_part1=other_table.columnANDref_table.key_column_part2=1;
ref_or_null
This join type is like ref, but with the addition that MySQL does an extra search for rows that contain NULL values. This join
type optimization is used most often in resolving subqueries. In the following examples, MySQL can use a ref_or_null join to process ref_table:
这种连接类型与ref类似,但是除此之外,MySQL还对包含NULL值的行进行额外的搜索。 这种连接类型优化最常用于解析子查询。 在以下示例中,MySQL可以使用ref_or_null连接来处理ref_table:
SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;
unique_subquery
This type replaces eq_ref for some IN subqueries of the following form,is just an index lookup function that replaces the subquery completely
for better efficiency.
这种类型替换了以下形式的一些IN子查询的eq_ref,只是一个索引查找函数,它可以完全替代子查询以提高效率。
value IN (SELECT primary_key FROM single_table WHERE some_expr)
range
Only rows that are in a given range are retrieved, using an index to select the rows. The key column in the output row indicates which
index is used. The key_len contains the longest key part that was used. The ref column is NULL for this type. range can be used when a key column is compared to a constant using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators:
只有在给定范围内的行才能被检索,使用索引来选择行。 输出行中的key column指示哪一个索引被使用。 key_len包含使用的最长key部分。 这个类型的ref列是NULL。
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
The index join type is the same as ALL, except that the index tree is scanned. This occurs two ways:
If the index is a covering index for the queries and can be used to satisfy all data required from the table,
only the index tree is scanned. In this case, the Extra column says Using index. An index-only scan usually is
faster than ALL because the size of the index usually is smaller than the table data.
A full table scan is performed using reads from the index to look up data rows in index order. Uses index does not
appear in the Extra column. MySQL can use this join type when the query uses only columns that are part of a single index.
索引连接类型与ALL相同,只是索引树被扫描。 这发生在两个方面: 如果索引是查询的覆盖索引,并且可用于满足表中所需的所有数据,则只扫描索引树。 在这种情况下,额外列说使用索引。 仅索引扫描通常比ALL快,因为索引的大小通常小于表数据。 全表扫描使用索引中的读取来按索引顺序查找数据行。 使用索引不会出现在Extra列中。 当查询只使用属于单个索引一部分的列时,MySQL可以使用这种连接类型。
第二部分:数据演示
Server version: 10.0.24-MariaDB-7 Ubuntu 16.04
1.查看表数据类型
MariaDB [member]> show create table test; | test | CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL,
`price` decimal(10,2) NOT NULL,
`brand` varchar(100) NOT NULL,
`consume_time` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `price` (`price`),
KEY `member_id` (`member_id`),
KEY `member_price` (`member_id`,`price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
有一个主键ID 两个普通索引 还有一个联合索引
2.查看数据大小
MariaDB [member]> select count(*) from test;
+----------+
| count(*) |
+----------+
| 597383 |
+----------+
3.主键 Using index 演示
MariaDB [member]> explain SELECT id from test where id = 100;
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | test | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
MariaDB [member]> explain SELECT * from test where id = 100;
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | test | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+------+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
type是const类型 如果是只筛选ID列 则Extra会显示Using index 说明只需要遍历索引就可以获取需要的数据
4.辅助索引 Using index 演示
MariaDB [member]> explain SELECT price from test where price=1;
+------+-------------+-------+------+---------------+-------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+-------+---------+-------+------+-------------+
| 1 | SIMPLE | test | ref | price | price | 5 | const | 1874 | Using index |
+------+-------------+-------+------+---------------+-------+---------+-------+------+-------------+
type是ref格式的 用到了键 price 由于只需要筛选索引列 索引 提示信息是Using index
MariaDB [member]> explain SELECT price from test where price<100;
+------+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
| 1 | SIMPLE | test | range | price | price | 5 | NULL | 117580 | Using where; Using index |
+------+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
这里type是range, key是price 说明用到了索引。提示信息Using where ,Using index 。由于只需要price 所以遍历索引列即可得到数据 ,后面mysql会再根据where条件筛选
5.Using index condition 演示
MariaDB [member]> explain SELECT * from test where member_id<10;
+------+-------------+-------+-------+------------------------+-----------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+------------------------+-----------+---------+------+------+-----------------------+
| 1 | SIMPLE | test | range | member_id,member_price | member_id | 4 | NULL | 62 | Using index condition |
+------+-------------+-------+-------+------------------------+-----------+---------+------+------+-----------------------+
type 是range 可以看到提示信息是 Using index condition
MariaDB [member]> explain SELECT * from test where price>10;
+------+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | test | ALL | price | NULL | NULL | NULL | 595835 | Using where |
+------+-------------+-------+------+---------------+------+---------+------+--------+-------------+
type是all 可以看到 key 列是NULL 且提示信息只有 Using where。与上面的策略不同 我的理解是 这里mysql判断需要的遍历的数据比较多 没有走索引 这样更快 因为回查主索引 也比较耗时耗力
mysql EXPLAIN Join Types 手册解释 及数据实操的更多相关文章
- Mysql EXPLAIN列的解释
转自:http://blog.chinaunix.net/uid-540802-id-3419311.html explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择 ...
- mysql中explain的type的解释
type -- 连接类型 type意味着类型,这里的type官方全称是“join type”,意思是“连接类型”,这样很容易给人一种错觉觉得必须需要俩个表以上才有连接类型.事实上这里的连接类型并非字面 ...
- mysql explain字段意思解释
mysql explain字段意思解释 explain包含id.select_type.table.type.possible_keys.key.key_len.ref.rows.extra字段 id ...
- [mysql] mysql explain 使用
explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 先解析一条sql语句,看出现什么内容 EXPLAINSELECTs.uid, ...
- MySQL Explain 结果解读与实践
Explain 结果解读与实践 基于 MySQL 5.0.67 ,存储引擎 MyISAM . 注:单独一行的"%%"及"`"表示分隔内容,就象分开&qu ...
- 知识点:Mysql 索引原理完全手册(2)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 八. 联合索引与覆盖索引 ...
- (转)mysql explain详解
原文:http://www.cnblogs.com/xuanzhi201111/p/4175635.html http://yutonger.com/18.html http://www.jiansh ...
- mysql explain type详解
本文转载自最官方的 mysql explain type 字段解读 读了很多别人的笔记都杂乱不堪,很少有实例,什么都不如原装的好,所以当你读到我的笔记的时候如果觉得说的不明白,最好参考官方的手册. 我 ...
- 【转载】 mysql explain用法
转载链接: mysql explain用法 官网说明: http://dev.mysql.com/doc/refman/5.7/en/explain-output.html 参数: htt ...
随机推荐
- springcloud(一) 服务拆分
一般我们的项目如果需要从单应用服务升级到微服务,必须要将原来的服务做拆分,我这边的拆分也是基于将之前spb-demo的springboot单应用做拆分,拆分出三个应用,spb-brian-query- ...
- 第五篇 .NET高级技术之CTS、CLS、CLR
CTS.CLS.CLR 1. .Net平台下不只有C#语言,还有VB.Net.F#等语言.IL是程序最终编译的可以执行的二进制代码(托管代码),不同的语言最终都编译成标准的IL(中间语言,MSIL): ...
- vlc media player
还是很好用的目前来看 倍速播放: [ 减速播放 ] 加速播放 = 恢复原速度
- Hadoop工作流--ChainMapper/ChainReducer?(三)
不多说,直接上干货! Hadoop的ChainMapper和ChainReducer使用案例(链式处理) 什么是ChainMapper/ChainReducer?
- [转]VC中调用外部exe程序方式
本文转自:http://blog.sina.com.cn/s/blog_486285690100ljwu.html 目前知道三种方式:WinExec,ShellExecute ,CreateProce ...
- js调用本地程序
前几天,做项目时候用到js调用本地的程序,找了好多资料,一种是写入注册表,一种是写一个浏览器插件,相对来说,写一个注册表更简单一点,因为需求很紧.下面就是我的总结,希望可以对你们有所帮助,具体从哪里找 ...
- AJPFX谈JAVA新手问题之异常处理使用不当
★空的 catch 语句块 犯这种错误的人比较少,一般发生在刚学会 Java 或者刚参加工作不久的人身上. 所谓“空 catch 语句块”就是在 catch 语句块中没有对异常作任何处理(比如记错误日 ...
- hihocoder1736 最大的K-偏差排列
思路: 容易写错的贪心题. 实现: #include <bits/stdc++.h> using namespace std; int main() { int n, k; while ( ...
- 利用伪类写一个自定义checkbox和radio
首先是效果图来一张 再来一张html结构 关键的CSS来了~ 首先呢要把input标签设置为display: none; 因为自定义的原理是通过label的for属性,来点击label转向为点击in ...
- EJB 使用多个数据源问题
编辑 删除 如果在JBoss中同时使用俩个数据源就会发生如下异常: Transaction is not active: tx=TransactionImple < ac, BasicActio ...