MYSQL中的type:index 和 Extra:Using index

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 原创水平有限,如有错误请指出 考虑下面执行计划中的TYPE和Extra +----+-------------+--------+------------+-------+---------------+------+---------+------+------...
原创水平有限,如有错误请指出


考虑下面执行计划中的TYPE和Extra

+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | testud | NULL       | index | NULL          | id2  | 10      | NULL |    3 |   100.00 | Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+

type:index 不使用索引B+树结构,只使用索引叶子结点链表结构进行扫描,我们知道在索引的叶子结点有一个叶子结点之间的双向指针,
           并且叶子结点的数据是排序好的。他和ALL的方式类似,访问效率并不高,其主要的应用场景为用于避免order by使用using filesort
           也就是避免排序。他是一种访问数据的方式,和const、ref、eq_ref等一样
Extra:Using index  当二级索引包含了所有的查询需要的所有字段的时候,select查询只需要通过索引及可以
                   获得全部的数据,那么就不需要回表了。注意这里全部数据是条件谓词和查询字段的全部
                   总和比如
                   select id1 from test where id2=1;
                   这个索引必须包含id1和id2,这里有种特殊的情况叫做Index Extensions在后面说明
                   它可以考虑B+树结构如使用type:ref也可以不考虑使用type:index
                   一般来说索引的大小要远远小于表的大小,不管从回表还是读取物理文件的大小来说,使用
                   Using index 都可以提高查询性能。也叫索引覆盖扫描

这两个地方是让人经常容易混淆的,并且它们并不是总是一起出现(虽然可能性不小),实际上他们没有必然的联系
下面是我的测试表结构
mysql> show create table testud;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                                                                        |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| testud | CREATE TABLE `testud` (
  `id1` int(11) NOT NULL,
  `id2` int(11) DEFAULT NULL,
  `id3` int(11) DEFAULT NULL,
  `id4` int(11) DEFAULT NULL,
  PRIMARY KEY (`id1`),
  KEY `id2` (`id2`,`id3`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)

1、可以单独的出现type:index
mysql> explain select * from testud force index(id2) order by id2;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | testud | NULL       | index | NULL          | id2  | 10      | NULL |    3 |   100.00 | NULL  |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

这里只是代表type=index避免的排序,但是需要从头到尾使用双向链表来访问整个叶子结点
2、可以单独出现Extra:Using index
mysql> explain select id2 from testud where id2=1;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | testud | NULL       | ref  | id2           | id2  | 5       | const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
这里type为ref,代表通过一个非唯一的索引进行了单个值的扫描 id2=1,也就是这里的(id2,id3)是非唯一索引,而1是单个值,他考虑了索引
的B+树的结构也就是不仅仅考虑了叶子结点,需要从根结点到分支节点(如果有),再到叶子结点来完成id2=1这种条件的过滤
而因为id2包含在索引(id2,id3)中当然也就使用Using index 就可以了。
从上面两种情况来看type:index和Extra:Using index并没有必然的联系。他们各自代表值的意思

3、共同出现这个就很简单了。
mysql> explain select id2 from testud;
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | testud | NULL       | index | NULL          | id2  | 10      | NULL |    3 |   100.00 | Using index |
+----+-------------+--------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)


需要从头到尾使用双向链表来访问整个叶子结点,而索引id2包含了全部的需要的数据。


这里还需要提高Using index的一种特殊场景,也是很多人问过的。官方文档叫做
9.2.1.7 Use of Index Extensions
简单来说比如上面的KEY `id2` (`id2`,`id3`),我们知道叶子结点除了索引自己的数据实际上还有主键的数据在末尾,这个我在前面
已经做过验证,参考:
http://blog.itpub.net/7728585/viewspace-2128817/
这个时候实际上索引id2 包含了 id2 id3 id1 这样排列的数据如果id2相等按照id3排序如果id3相等按照id1排序的这样一种结构,那么
我们的using index就扩大了范围比如下的语句:
mysql> explain select id1,id2,id3 from testud where id2=1;
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | testud | NULL       | ref  | id2           | id2  | 5       | const |    1 |   100.00 | Using index |
+----+-------------+--------+------------+------+---------------+------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)


我们可以看到Using index是生效的。具体可以参考官方文档

最后我们来简单说明一下ORACLE中的索引覆盖扫描
ORACLE中分为2种
index fast full scan:主要按照磁盘物理顺序进行扫描,我们知道链表之所以叫做链表是因为它有指向前或者后的指针比如C语言中经常用
                     *next *pr 来表示前后,既然是指向关系在物理上不一定是有序的。但是这种方式更快,可以使用物理上的多块读取
                     但是其返回数据并不有序,仔细考虑实际上MYSQL中没有这种方式
index full scan:这种访问返回就是有序的,他有点像MYSQL中的index+Using index 方式进行扫描,同样他也是为了避免排序而大量使用
                 的。


作者微信:

               






相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 存储 关系型数据库
MySQL - order by 出现 using filesort根因分析及优化
MySQL - order by 出现 using filesort根因分析及优化
50 0
|
11月前
|
存储 SQL 缓存
一文带你了解MySQL之Adaptive Hash Index
在InnoDB体系架构图的内存结构中,还有一块区域名为:Adaptive Hash Index,翻译成中文:自适应哈希索引,缩写:AHI,它是一个纯内存结构,我们今天就来了解它。
743 0
|
5月前
|
关系型数据库 MySQL 数据库
Mysql中key与index区别
Mysql中key与index区别
|
6月前
|
存储 SQL 关系型数据库
MySQL 优化 index merge(索引合并)引起的死锁分析(强烈推荐)
生产环境出现死锁流水,通过查看死锁日志,看到造成死锁的是两条一样的update语句(只有where条件中的值不同),如下:
|
9月前
|
关系型数据库 MySQL 索引
不会2023年你还不知道Mysql中index、primary key、unique key、foreign key是什么和如何创建吧?
不会2023年你还不知道Mysql中index、primary key、unique key、foreign key是什么和如何创建吧?
59 0
|
11月前
|
关系型数据库 MySQL 索引
MySQL 8 不可见索引 invisible index
不可见索引 创建不可见索引
|
11月前
|
关系型数据库 MySQL 索引
MySQL - 索引下推 Index Condition Pushdown 初探
MySQL - 索引下推 Index Condition Pushdown 初探
67 0
|
11月前
|
存储 关系型数据库 MySQL
MySQL的索引条件下推(index condition pushdown,ICP)
索引下推:不符合索引最左前缀原则,却还能利用复合索引的其他字段,减少回表次数。 最左前缀可用于在索引中定位记录。那不符合最左前缀的部分,会怎样
73 0
|
存储 SQL JSON
【MySQL从入门到精通】【高级篇】(二十五)EXPLAIN中ref、rows、filtered、Extra字段的剖析
上一篇文章我们介绍了 【MySQL从入门到精通】【高级篇】(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析,重点介绍了EXPLAIN命令的select_type,partition,type,key,key_len 字段含义。这篇文章我将接着介绍剩余字段的含义。本文会介绍ref、rows、filtered、Extra这几个字段。比较重要的两个字段是rows、Extra
1072 0
【MySQL从入门到精通】【高级篇】(二十五)EXPLAIN中ref、rows、filtered、Extra字段的剖析
|
存储 关系型数据库 MySQL
简述 MySQL 的主键 PRIMARY KEY 和唯一键 UNIQUE INDEX
简述 MySQL 的主键 PRIMARY KEY 和唯一键 UNIQUE INDEX
254 0
简述 MySQL 的主键 PRIMARY KEY 和唯一键 UNIQUE INDEX

推荐镜像

更多