mysql利用覆盖索引避免回表优化查询
作者:家有四只胖加菲 发布时间:2024-01-12 21:34:11
前言
说到覆盖索引之前,先要了解它的数据结构:B+树。
先建个表演示(为了简单,id按顺序建):
id | name |
1 | aa |
3 | kl |
5 | op |
8 | aa |
10 | kk |
11 | kl |
14 | jk |
16 | ml |
17 | mn |
18 | kl |
19 | kl |
22 | hj |
24 | io |
25 | vg |
29 | jk |
31 | jk |
33 | rt |
34 | ty |
35 | yu |
37 | rt |
39 | rt |
41 | ty |
45 | qt |
47 | ty |
53 | qi |
57 | gh |
61 | dh |
以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。
非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。
B+树
B+树和B树是mysql索引的常用数据结构,B+树是B树的进一步优化,将上面的表转成图分析一下:
B+树的特点:
1.B+ 树非叶子节点上是不存储数据的,仅存储键值
2.叶子节点的数据是按照顺序排列的
3. B+ 树中各个页之间是通过双向链表连接
聚簇索引和非聚簇索引
B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。
聚簇索引:
以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。
这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。
这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。
非聚簇索引:
以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。
非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。
如何用覆盖索引避免回表
为什么明明用了非主键索引还会回表,简单说就是非主键索引是非聚簇索引,在B+树叶子节点中只保存主键和该非主键索引,一次查询只能查到这两个字段,如果想查三个字段,就必须再查一次聚簇索引,这就是回表。
举个例子,表中新增一个字段age,我们用name建一个索引(非聚簇索引)
id | name | age |
10 | zs | 23 |
7 | ls | 54 |
13 | ww | 12 |
5 | zl | 76 |
8 | xw | 23 |
12 | xm | 43 |
17 | dy | 21 |
select id,name from user where name = 'zs';
能够命中name索引,索引叶子节点存储了主键id,通过name的索引树即可获取id和name,无需回表,符合索引覆盖,效率较高。
select id,name,age from user where name = 'zs';
能够命中name索引,索引叶子节点存储了主键id,但age字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取age字段,效率会降低。
结论:那怎么做才能避免回表呢?很简单,将单列索引(name)升级为联合索引(name,age).
总结
来源:https://www.cnblogs.com/iceggboom/p/14366252.html


猜你喜欢
- 如下所示:import h5pyimport numpy as np#HDF5的写入:imgData = np.zeros((2,4))f
- 本文实例讲述了python实现unicode转中文及转换默认编码的方法。分享给大家供大家参考,具体如下:一、在爬虫抓取网页信息时常需要将类似
- 研究(2)中讨论了栅格系统的基础知识。这一篇将集中探讨栅格系统的粒度问题。(注:如非特别指明,栅格系统均指24列960栅格系统)淘宝的首页(
- flush()方法刷新内部缓冲区,像标准输入输出的fflush。这类似文件的对象,无操作。Python关闭时自动刷新文件。但是可
- 一般事件 事件 浏览器支持 描述onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击onDblClick
- 大家好,我是煎蛋哥!上篇文章聊到了 Python 实现大 * 票自由的完整流程如何使用 Python 实现彩票自由(大乐透)和体彩大乐透类似
- 整理文档,搜刮出一个vue 计时器组件的代码,稍微整理精简一下做下分享。<template> <div>  
- 主要是用函数torch.nn.utils.rnn.PackedSequence()和torch.nn.utils.rnn.pack_padd
- 当我们想指定每一层的学习率时:optim.SGD([ &
- git还原到某次commit并强制推送远程不可逆提交一、reset1.git log查看提交记录git log2.选择某次提交的commit
- 需要处理原始的音频,所以给服务器的环境安装librosa的包pip install librosa直接pip install librosa
- 这篇文章主要介绍了python如何使用socketserver模块实现并发聊天,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定
- 在进行CSS网页布局的时候,我们经遇到刷新要保留表单里内容的时候,习惯的做法使用cookie,但是那样做实在是很麻烦,css中的behavi
- 功能很简单,代码也很简洁,这里就不多废话了。package mainimport ( "fmt
- 注:本文档做了两个MYSQL实例,多个实例方法以此类推LINUX操作系统:centOS6.3 64bit(安装了系统默认开发包)数据库一:M
- 我自己的一个项目,需要同时对65536个文件进行多次写操作。如果先全部打开所有的文件,然后重复写,最后关闭所有的文件。那么第一次写操作全部完
- 发现问题今天准备学习爬虫的scrapy模块,在这之前需要安装许多别的模块,Twisted就是其一一开始想着直接用pycharm来安装就行了,
- <1>IsArray 函数 返回 Boolean 值指明某变量是否为数组。 语法 IsArray(var
- 在这个周末刚刚写出来的python桌面应用--网络聊天室,主要通过pyqt5作为桌面应用框架,socket作为网络编程的框架,从而实现包括客
- 前端css中用到less,在pycharm中安装配置less操作步骤如下:1.点开setting,在Plugins中搜索node.js(安装