当前位置:网站首页>MySQL中回表的代价
MySQL中回表的代价
2022-07-06 17:21:00 【秀强】
回表的代价
对于下面这个查询语句来说:SELECT * FROM single_ table WHERE key1 > 'a' AND key1 < 'c';
我们可以选择下面这两种方式来执行。
- 以全表扫描的方式执行该查询
也就是直接扫描全部的聚簇索引记录,针对每一条聚簇索引记录,都判断搜索条件是否成立,如果成立则发送到客户端,否则跳过该记录。 - 使用 idx_key1 执行该查询
可以根据搜索条件 key1>a’ AND key1 < ‘c’ 得到对应的扫描区间(‘a’,‘c’),然后扫描该扫描区间中的二级索引记录。由于 idx_key1 索引的叶子节点存储的是不完整的用户记录,仅包含 key1、id 这两个列,而查询列表是*,这意味着我们需要获取每条二级索引记录对应的聚簇索引记录,也就是执行回表操作,在获取到完整的用户记录后再发送到客户端。
对于使用 InnoDB 存储引擎的表来说,索引中的数据页都必须存放在磁盘中,等到需要时再加载到内存中使用。这些数据页会被存放到磁盘中的一个或者多个文件中,页面的页号对应着该页在磁盘文件中的偏移量。以 16KB 大小的页面为例,页号为 0 的页面对应着这些文件中偏移量为 0 的位置,页号为 1 的页面对立着这些文件中偏移量为 16KB 的位置。
B+树的每层节点会使用双向链表连接起来,上一个节点和下一个节点的页号可以不必相邻。不过在实际实现中,InnoDB 还是尽量让同一个索引的叶子节点的页号按照顺序排列。
也就是说,idx_key1 在扫描区间(‘a’,‘e’)中的二级索引记录所在的页面的页号会尽可能相邻。即使这些页面的页号不相邻,但起码一个页面可以存放很多记录,也就是说在执行完一次页面 I/O 后,就可以把很多二级索引记录从磁盘加载到内存中。总而言之,就是读取在扫描区间(‘a’,‘e’)中的二级索引记录时,所付出的代价还是较小的。不过扫描区间(‘a’,‘e’)中的二级索引记录对应的 id 值的大小是毫无规律的,我们每读取一条二级索引记录,就需要根据该二级索引记录的 id 值到聚簇索引中执行回表操作。如果对应的聚簇索引记录所在的页面不在内存中,就需要将该页面从磁盘加载到内存中。由于要读取很多 id 值并不连续的聚簇索引记录,而且这些聚簇索引记录分布在不同的数据页中,这些数据页的页号也毫无规律,因此会造成大量的随机 I/O。
需要执行回表操作的记录越多,使用二级索引进行查询的性能也就越低,某些查询宁愿使用全表扫描也不使用二级索引。比如,假设 key1 值在 'a’~’c’之间的用户记录数量占全部记录数量的 99% 以上,如果使用 idx_key1 索引,则会有 99% 以上的 id 值需要执行回表操作。这还不如直接执行全表扫描。
那么在执行查询时,什么时候采用全表扫描,什么时候使用二级索引+回表的方式呢?这就是查询优化器应该做的工作。查询优化器会事先针对表中的记录计算一些统计数据,然后再利用这些统计数据或者访问表中的少量记录来计算需要行回表操作的记录数。如果需要执行回表操作的记录数越多,就越倾向于使用全表扫描,反之则倾向于使用二级索引+回表的方式。当然,查询优化器所做的分析工作没有这么简单,但大致上是这样一个过程。
一般情况下,可以给查询语句指定 LIMIT 子句来限制查询返回的记录数,这可能会让查询优化器倾向于选择使用二级索引+回表的方式进行查询,原因是回表的记录越少,性能提开就越高。比如,上面的查询语句可以改写成下面这样:SELECT * FROM single_table WHERE key1 >'a' AND key1 < 'c' LIMIT 10;
添加了 LIMIT 10 子句后的查询语句更容易让查询优化器采用二级索引+回表的方式来执行。
对于需要对结果进行排序的查询,如果在采用二级索引执行查询时需要执行回表操作的记录特别多,也倾向于使用全表扫描+文件排序的方式执行查询。比如下面这个查询语句:SELECT * FROM single_table ORDER BY key1;
由于查询列表是 *
,如果使用二级索引进行排序,则需要对所有二级索引记录执行回表操作。这样操作的成本还不如直接遍历聚簇索引然后再进行文件排序低,所以查询优化器会倾向于使用全表扫描的方式执行查询。如果添加了 LIMIT 子句,比如下面这个查询语句:SELECT * FROM single_table ORDER BY key1 LIMIT 10;
这个查询语句需要执行回表操作的记录特别少,查询优化器就会倾向于使用二级索引+回表的方式来执行。
边栏推荐
- Levels - UE5中的暴雨效果
- Attention SLAM:一種從人類注意中學習的視覺單目SLAM
- "Exquisite store manager" youth entrepreneurship incubation camp - the first phase of Shunde market has been successfully completed!
- C Primer Plus Chapter 14 (structure and other data forms)
- There is an error in the paddehub application
- Meet the level 3 requirements of ISO 2.0 with the level B construction standard of computer room | hybrid cloud infrastructure
- 深度学习简史(二)
- fastDFS数据迁移操作记录
- Chapter 5 DML data operation
- Zynq transplant ucosiii
猜你喜欢
New feature of Oracle 19C: automatic DML redirection of ADG, enhanced read-write separation -- ADG_ REDIRECT_ DML
[牛客] B-完全平方数
pyflink的安装和测试
【JVM调优实战100例】05——方法区调优实战(下)
Deep learning environment configuration jupyter notebook
Part V: STM32 system timer and general timer programming
Activereportsjs 3.1 Chinese version | | | activereportsjs 3.1 English version
Part VI, STM32 pulse width modulation (PWM) programming
Attention SLAM:一種從人類注意中學習的視覺單目SLAM
Dell筆記本周期性閃屏故障
随机推荐
深入探索编译插桩技术(四、ASM 探秘)
Leetcode (547) - number of provinces
Chapter 5 DML data operation
再聊聊我常用的15个数据源网站
Batch obtain the latitude coordinates of all administrative regions in China (to the county level)
What is time
Configuring the stub area of OSPF for Huawei devices
做微服务研发工程师的一年来的总结
Dell筆記本周期性閃屏故障
Slam d'attention: un slam visuel monoculaire appris de l'attention humaine
第六篇,STM32脉冲宽度调制(PWM)编程
Segmenttree
[force buckle]41 Missing first positive number
View remote test data and records anytime, anywhere -- ipehub2 and ipemotion app
Data type of pytorch tensor
动态规划思想《从入门到放弃》
什么是时间
随时随地查看远程试验数据与记录——IPEhub2与IPEmotion APP
mongodb客户端操作(MongoRepository)
Make a simple graphical interface with Tkinter