前言
Github:https://github.com/HealerJean
博客:http://blog.healerjean.com
数据准备
mysql优化器在数据量不同的情况下,也会到结果产生影响
参数 | 含义 |
id | 查询的标识符 |
select_type | SELECT 查询的类型. |
table | 查询的是哪个表 |
partitions | 匹配的分区 |
type | 判断是什么扫描查询 比如:ALL,Index,Rank |
possible_keys | 可能选用的索引 |
key | 确切使用到的索引 |
key_len | 索引长度(通过观察这个可以判断联合索引使用了几列,很有用) |
ref | 哪个字段或常数与 key 一起被使用 |
rows | 显示此查询一共扫描了多少行. 这个是一个估计值. |
filtered | 表示此查询条件所过滤的数据的百分比 |
extra | 额外的信息 |
1、select_type
select_type | 说明 |
| 简单查询 |
| 联合查询 |
| 子查询 |
| 联合查询的结果 |
| 最外层查询 |
1.1、SIMPLE 简单查询
解释:此查询不包含 UNION 查询或子查询
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100 | NULL |
1.2、UNION 联合查询
解释:表示此查询是 UNION 的第二或随后的查询
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | PRIMARY | user | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100 | NULL |
2 | UNION | user | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100 | NULL |
NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
1.3、SUBQUERY 子查询
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | PRIMARY | o | NULL | ALL | PRIMARY | NULL | NULL | NULL | 7 | 85.71 | Using where |
2 | SUBQUERY | b | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100 | Using index |
1.4、UNION RESULT 联合查询的结果
解释:在
1.2
中介绍过了
1.5、PRIMARY 最外层查询
解释:在
1.2
和 1.3
中介绍过
2、type
解释:它提供了判断查询是否高效的重要依据依据. 通过
type
字段, 我们判断此次查询是 全表扫描
还是 索引扫描
等,要和Extra同时观察会更好性能:ALL < index < range ~ index_merge < ref < eq_ref < const < system
2.1、ALL
解释:全表扫描
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100 | NULL |
2.2、index
解释:表示全索引扫描 (索引覆盖)和ALL类似
1、
index
: 表示全索引扫描, 和 ALL 类型类似, 只不过 ALL 类型是全表扫描, 而 index 类型则仅仅扫描所有的索引, 而不扫描数据. 其实就是讲 查询条件 写上索引的字段2、
index
类型通常出现在: 所要查询的数据直接在索引树中就可以获取到, 而不需要扫描数据. 当是这种情况时, Extra 字段 会显示 Using index
3、
index
类型的查询虽然不是全表扫描, 但是它扫描了所有的索引, 因此比 ALL 类型的稍快.
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | index | NULL | idx_name | 195 | NULL | 5 | 100 | Using index |
2.3、range
解释:索引范围内查询 ,通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 3 | 100 | Using index condition |
2.4、INDEX_MERGE
解释:合并索引,使用多个单列索引搜索
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | index_merge | PRIMARY,idx_name | PRIMARY,idx_name | 8,195 | NULL | 2 | 100 | Using union(PRIMARY,idx_name); Using where |
2.5、REF
解释:根据索引查找一个或多个值
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | ref | idx_name | idx_name | 195 | const | 1 | 100 | NULL |
2.6、eq_ref
解释:连接join查询时,使用primary key 或 unique类型,其实就是说索引唯一的关联查询
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | o | NULL | ALL | uk_user_id | NULL | NULL | NULL | 7 | 100 | NULL |
1 | SIMPLE | u | NULL | eq_ref | PRIMARY | PRIMARY | 8 | hlj_sql.o.ref_user_id | 1 | 100 | NULL |
2.7、const
解释:针对主键或唯一索引的等值查询扫描,只有一行
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | user | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100 | Using index |
2.8、system
解释:表中仅仅有一条数据,这个是特殊的const查询
3、possible_keys
可能用到的索引,看 4
4、key
**解释:表示 MySQL 在查询时, 真实使用到的索引, **
即使有些索引在
possible_keys
中出现, 但是并不表示此索引会真正地被 MySQL 使用到. MySQL 在查询时具体使用了哪些索引, 由 key
字段决定…
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
1 | SIMPLE | order_info | NULL | const | PRIMARY,uk_user_id | PRIMARY | 8 | const | 1 | 100 | NULL |
5、key_len
解释: 使用索引字节长度,这个字段可以评估联合索引是否完全被使用
5.1、字符串
类型 | 索引长度 |
char(n) | n |
varchar(n) | 如果是 utf8,3 n + 2 |
varchar(n) | 如果是 utf8mb4 ,则是 4 n + 2 字节. |
5.2、数值类型:
类型 | 索引长度 |
TINYINT | 1 |
SMALLINT | 2 |
MEDIUMINT | 3 |
INT | 4 |
BIGINT | 8 |
float | 4 |
double | 8 |
decimal |
5.3、时间类型
类型 | 长度 |
year | 1 |
date | 4 |
time | 3 |
datetime | 8 |
timestamp | 4 |
6、rows
显示此查询一共扫描了多少行. 这个是一个估计值.
7、Extra
解释 : 额外信息,优化器会在索引存在的情况下,通过符合 RANGE 范围的条数和总数的比例来选择是使用索引还是进行全表遍历,
具体案例例具体分析,不要把这里想复杂了,就是一个额外的信息而已
名词解释:
回表:表示即使使用索引筛选了,但是查询的字段不是全部都是索引列
Extra | 说明 |
NULL | 查询的不全都是索引 |
using index | 使用覆盖索引的时候就会出现 |
using index condition | 查询条件是索引的一个范围 |
using where | 查询条件包含普通的条件 |
Using filesort | 排序 不能通过索引达到排序效果 |
using index
> using where
> using index condition
,如果不需要回表查询数据,效率上应该比较快的