回表查询的说明

你可能从来都没有听说过回表一词,但是你在实际工作中肯定用过回表。如果还没有听过回表,那我相信不管你看多少 SQL 优化的知识,都还只是停留在表面。即使你参考学习过我前面的这篇文章《MySQL 性能优化神器 Explain 使用教程》。

一条SQL语句的查询过程

我们先来看看什么是回表?

通俗的讲就是,如果索引的列在 select 所需获得的列中(因为在 mysql 中索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。

根据这个概念,当你使用 Explain 执行查询计划时,当结果中 Extra 出现了 using index、using where、using index condition 等你就认为使用了过滤条件,使用了索引,SQL 优化的还不错。这其实是一种错误的认识。

因为,使用了索引并不代表查询就最优。从 using index condition、using index & using where 等可以看出,这条 SQL 语句其实是进行了回表的。

还有些时候,你查看 Explain 执行计划后,发现明明走了索引,为什么还是慢?这里面可能就是存在回表了。下面我们通过一个例子来说明什么是回表。先创建一张表,sql 语句如下:

create table xttblog(
    id int primary key,
    k int not null,
    name varchar(16),
    index (k)
)engine = InnoDB;

然后,我们再执行下面的 SQL 语句,插入几条测试数据。

INSERT INTO xttblog(id, k, name) VALUES(1, 2, ‘xttblog‘),
    (2, 1, ‘业余草‘),
    (3, 3, ‘业余草公众号‘);

假设,现在我们要查询出 id 为 2 的数据。那么执行 select * from xttblog where ID = 2; 这条 SQL 语句就不需要回表。原因是根据主键的查询方式,则只需要搜索 ID 这棵 B+ 树。主键是唯一的,根据这个唯一的索引,MySQL 就能确定搜索的记录。

但当我们使用 k 这个索引来查询 k = 2 的记录时就要用到回表。select * from xttblog where k = 2; 原因是通过 k 这个普通索引查询方式,则需要先搜索 k 索引树,然后得到主键 ID 的值为 1,再到 ID 索引树搜索一次。这个过程虽然用了索引,但实际上底层进行了两次索引查询,这个过程就称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

我这里表里的数据量比较少,如果数据量大的话,你能很明显的看出两次查询所用的时间,很明显使用主键查询效率更高。

原文地址:https://www.cnblogs.com/tuanz/p/11806017.html

时间: 2024-11-07 21:18:01

回表查询的说明的相关文章

(MYSQL)回表查询原理,利用联合索引实现索引覆盖

一.什么是回表查询? 这先要从InnoDB的索引实现说起,InnoDB有两大类索引: 聚集索引(clustered index) 普通索引(secondary index) InnoDB聚集索引和普通索引有什么差异? InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引: (1)如果表定义了PK,则PK就是聚集索引: (2)如果表没有定义PK,则第一个not NULL unique列是聚集索引: (3)否则,InnoDB会创建一个隐藏的row-id作为聚集索

mysql如何避免回表查询

<迅猛定位低效SQL?>留了一个尾巴: select id,name where name='shenjian' select id,name,sex where name='shenjian' 多查询了一个属性,为何检索过程完全不同? 什么是回表查询? 什么是索引覆盖? 如何实现索引覆盖? 哪些场景,可以利用索引覆盖来优化SQL? 这些,这是今天要分享的内容. 画外音:本文试验基于MySQL5.6-InnoDB. 一.什么是回表查询? 这先要从InnoDB的索引实现说起,InnoDB有两大类

什么是MYSQL回表查询

转自:如何避免回表查询?什么是索引覆盖? <迅猛定位低效SQL?>留了一个尾巴: select id,name where name=‘shenjian’ select id,name,sex where name=‘shenjian’ 多查询了一个属性,为何检索过程完全不同? 什么是回表查询? 什么是索引覆盖? 如何实现索引覆盖? 哪些场景,可以利用索引覆盖来优化SQL? 这些,这是今天要分享的内容. 画外音:本文试验基于MySQL5.6-InnoDB. 一.什么是回表查询? 这先要从Inn

ORACLE回表(一)

要写出高效的SQL,那么必须必须得清楚SQL执行路径,介绍如何提高SQL性能的文章很多,这里不再赘述,本人来谈谈如何从 减少SQL回表次数 来提高查询性能,因为回表将导致扫描更多的数据块. 我们大家都知道,数据库表中数据存储都是以块为单位,称为数据块:表中每行数据都有唯一的地址标志ROWID. 举个例子: select a from test_db where b=5 A.假设b上没有索引 1.那么该条SQL将进行表扫描,扫描所有该表的数据块 2.从数据块中找到记录,并且进行过滤 可想而知,没有

闪回版本查询

DBAs can use Oracle Flashback Version Query to retrieve the different versions of specific rows that existed during a given time interval. A row version is created whenever a COMMIT statement is executed.闪回版本的作用是查询指定行的不同的版本数据,也就是指定行在过去的不同值 规则:(查询真实表)

Power Pivot表属性无法切换回表预览模式的问题

近期Office365用户升级后解决了在Power Pivot中输入中文的问题,但是同时也带来了一个新的问题就是表属性窗口默认为“查询编辑器”模式,且无法切换回“表预览”模式. 本文和您分享在这种情况下如何对源数据进行更改操作. [导入时未进行筛选的情况]   从Excel文件导入数据到PowerPivot, 注意红色部分的信息: 文件名 - 记录了所抓取的Excel文件名称和位置信息 源表 -记录了数据所在的工作表信息(Sheet) 预览并筛选 - 此处我们没有进行任何筛选操作 数据导入后,我

数据库 day60,61 Oracle入门,单行函数,多表查询,子查询,事物处理,约束,rownum分页,视图,序列,索引

1.    oracle介绍 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.比如SilverStream就是基于数据库的一种中间件.ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能:作为一个关系数据库,它是一个完备关系的产品:作为分布式数据库它实现了分布式处理功能.但它的所有知识,只要在一种机型上学习

闪回表

查询需要闪回的时间的scn: select timestamp_to_scn(to_timestamp('2016-01-11 10:00:00','yyyy-mm-dd hh24:mi:ss')) as scn from dual; 如下为执行 SQL> flashback table yky.website to scn 4432168706; flashback table yky.website to scn 4432168706                         * ER

[课]10.1闪回查询的三种方式:闪回查询/闪回版本查询/闪回事务查询

数据库版本 1.1闪回查询演示 1.2闪回版本查询演示 1.3闪回事务查询演示 在做闪回事务查询时候,我们需要使用ORACLE提供的一个系统视图FLASHBACK_TRANSACTION_QUERY.闪回事务查询与闪回版本查询之间有着密切的关系,从刚才我们实验的闪回版本查询中可以知道有一个伪列VERSIONS_XID,那么闪回事务查询就是通过这个伪列与闪回版本查询发生关联. 我们现在查看一下该表的表结构: 开始演示: