什么时候不需要回表?
在下面这个表 T 中,如果我执行 select * from T where k between 3 and 5
,需要执行几次树的搜索操作,会扫描多少行?
create table T
(ID int primary key,k int NOT NULL DEFAULT 0,s varchar(16) NOT NULL DEFAULT '',index k (k)
)engine = InnoDB;insert into T
values (100, 1, 'aa'),(200, 2, 'bb'),(300, 3, 'cc'),(500, 5, 'ee'),(600, 6, 'ff'),(700, 7, 'gg');
现在,我们一起来看看这条 SQL 查询语句的执行流程:
在 k 索引树上找到 k=3 的记录,取得 ID = 300;
再到 ID 索引树查到 ID=300 对应的 R3;
在 k 索引树取下一个值 k=5,取得 ID=500;
再回到 ID 索引树查到 ID=500 对应的 R4;
在 k 索引树取下一个值 k=6,不满足条件,循环结束。
在这个过程中,回到主键索引树搜索的过程,我们称为回表。可以看到,这个查询过程读了 k 索引树的 3 条记录(步骤 1、3 和 5),回表了两次(步骤 2 和 4)。
在这个例子中,由于查询结果所需要的数据只在主键索引上有,所以不得不回表
。那么,有没有可能经过索引优化,避免回表过程呢?
覆盖索引
如果执行的语句是 select ID from T where k between 3 and 5
,这时只需要查 ID 的值,而 ID 的值已经在 k 索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,索引 k 已经“覆盖了”我们的查询需求,我们称为覆盖索引
。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
需要注意的是,在引擎内部使用覆盖索引在索引 k 上其实读了三个记录,R3~R5(对应的索引 k 上的记录项),但是对于 MySQL 的 Server 层来说,它就是找引擎拿到了两条记录,因此 MySQL 认为扫描行数是 2。
基于上面覆盖索引的说明,我们来讨论一个问题:在一个市民信息表上,是否有必要将身份证号和名字建立联合索引?
假设这个市民表的定义是这样的:
CREATE TABLE `tuser`
(`id` int(11) NOT NULL,`id_card` varchar(32) DEFAULT NULL,`name` varchar(32) DEFAULT NULL,`age` int(11) DEFAULT NULL,`ismale` tinyint(1) DEFAULT NULL,PRIMARY KEY (`id`),KEY `id_card` (`id_card`),KEY `name_age` (`name`, `age`)
) ENGINE = InnoDB
我们知道,身份证号是市民的唯一标识。也就是说,如果有根据身份证号查询市民信息的需求,我们只要在身份证号字段上建立索引就够了。而再建立一个(身份证号、姓名)的联合索引,是不是浪费空间?
如果现在有一个高频请求,要根据市民的身份证号查询他的姓名,这个联合索引就有意义了。它可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。当然,索引字段的维护总是有代价的。因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了。这正是业务 DBA,或者称为业务数据架构师的工作。
思考
- 依据其他索引查主键就不用回表了 (但是一般主键都是自增数字 有意义么???)
什么时候不需要回表?相关推荐
- mysql回表_到底什么情况下mysql innodb会发生回表操作?
谢邀 MySQL innodb的主键索引是簇集索引,也就是索引的叶子节点存的是整个单条记录的所有字段值,不是主键索引的就是非簇集索引,非簇集索引的叶子节点存的是主键字段的值.回表是什么意思?就是你执行 ...
- 生动的解释下什么是 MySQL 的“回表”?
1. 索引结构 要搞明白这个问题,需要大家首先明白 MySQL 中索引存储的数据结构.这个其实很多小伙伴可能也都听说过,B+Tree 嘛! B+Tree 是什么?那你得先明白什么是 B-Tree,来看 ...
- mysql非聚集索引区间查询_mysql的聚集索引和非聚集索引,回表查询,索引覆盖,最左前缀原则略解...
什么是聚集索引和非聚集索引 我们知道 Mysql 底层是用 B+ 树来存储索引的,且数据都存在叶子节点.对于 InnoDB 来说,它的主键索引和行记录是存储在一起的,因此叫做聚集索引(clustere ...
- oracle Database 10g后:闪回表
使用 Oracle Database 10g 中的闪回表特性,可以毫不费力地恢复被意外删除的表 以下是一个不该发生却经常发生的情况:用户删除了一个非常重要的表 - 当然是意外地删除 - 并需要尽快地恢 ...
- mysql联合索引查找过程_(MYSQL)回表查询原理,利用联合索引实现索引覆盖
一.什么是回表查询? 这先要从InnoDB的索引实现说起,InnoDB有两大类索引: 聚集索引(clustered index) 普通索引(secondary index) InnoDB聚集索引和普通 ...
- mysql版本的索引类型_【mysql】索引 回表 覆盖索引 索引下推
索引类型 索引类型分为主键索引和非主键索引.(一定要牢记,是怎么存储数据的) 主键索引的叶子节点存的是整行数据.在 InnoDB 里,主键索引也被称为聚簇索引(clustered index). 非主 ...
- mysql 回表 覆盖索引_MySQL 的覆盖索引与回表的使用方法
两大类索引 使用的存储引擎:MySQL5.7 InnoDB 聚簇索引 * 如果表设置了主键,则主键就是聚簇索引 * 如果表没有主键,则会默认第一个NOT NULL,且唯一(UNIQUE)的列作为聚簇索 ...
- mysql主键创建非聚集索引_什么是聚集索引,非聚集索引,索引覆盖,回表,索引下推...
聚集索引 我们先建如下的一张表 CREATE TABLE `student` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` var ...
- MySQL通过两表避免回表_mysql利用覆盖索引避免回表优化查询
前言 说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml ...
- MySQL 的覆盖索引与回表
一.两大类索引 聚簇索引: 如果表设置了主键,则主键就是聚簇索引 如果表没有主键,则会默认第一个NOT NULL,且唯一(UNIQUE)的列作为聚簇索引 以上都没有,则会默认创建一个隐藏的row_id ...
最新文章
- 空域滤波算法对比分析(超级全面哒)——Python代码
- 第三章 dubbo内核之ioc源码解析
- multi-statement not allow解决
- amazon linux 安装nginx,linux – NGINX不显示Amazon EC2实例上的默认页...
- Sleep()和wait()方法的区别
- poj 1185 NYOJ 85 炮兵阵地(状态压缩dp)
- 北斗导航 | NB-IoT——了解什么是NB-IoT,与短报文有什么关系
- elaseticsearch 配置ik分词器的热更新_Elasticsearch从入门到放弃:分词器初印象
- Jmeter 压测基础笔记
- 约瑟夫环问题2(顺序表+链表求解)
- HEVC---CompressCU 函数解析
- python mainloop作用_Tkinter中的mainloop应该如何理解?
- [Jscript]Js导出Excel
- [SQL]SQL server 常用代码
- WorkTool(一)企业微信群管理机器人实现
- 【性能测试】JSON工具 对比 fastjson jackson
- 【课程设计-毕业设计】机械设计课程设计选题-含设计说明书
- 小米路由器3G刷入OpenWrt
- 企业邮箱能帮企业带来哪些好处?
- 【001】快乐数字解题过程记录
热门文章
- 计算机基础(三):srpintf()函数小结
- 网站未备案不能访问,怎么用ip加端口的方式建站?
- EDI许可申请 简介
- MyBatis学习笔记01
- 用Python在图片上添加注释信息
- JSR-303校验-转载
- kafka是什么_Kafka凭什么速度那么快?
- 开放 接口 饿了么_饿了么口碑启动生态赋能计划 将在210城开放智慧餐厅业务合作窗口...
- Error:java: Compilation failed: internal java compiler error or source 1.5 提升版本
- 对称二叉树c++_二叉树:我对称么?