【B+树索引】索引的使用和注意事项

2023-09-22 13:43:19

一、索引的注意事项

上一篇 【B+树索引】索引页的结构含有可以快速查询的秘密 从索引页的角度认识了MySQL为了提升查询速率,使用了 B+ 树的数据结构对索引页进行了内存存储。以非叶子节点为目录项结构,叶子节点为用户记录。下面咱聊聊 InnoDB 中 B+ 树的索引的注意事项。(总结自《MySQL是怎样运行的》)

根节点是不会变的!

首先得明确一点是:聚簇索引不是咱创建的,它默认就在那的。刚开始就一个节点,那就是根节点,一个空的页。

随后有用户记录插进来了,就往这根节点的 User Records 中插入用户记录。

随着用户记录不断地增多, Free Space 部分空间逐渐减少直至为 0.

然后再插记录的话,由于根节点已经满了,此时就会发生页分裂。此时会寻一个页 a 将根节点的用户记录都复制到 页 a,再取一个页 b 存放新插入的记录。然后根节点现在即是目录项节点了,其用户记录就是主键值,映射的是页a和页b。如此往复…

此过程就是为了说明 B+ 树的根节点就是那一个,不会变,其页号不会改变

内节点中目录项记录的唯一性

就是说,二级索引也不一定会设置唯一和非空的约束的,对于二级索引记录来说,是先按二级索引列的值进行排序,在二级索引列值相同的情况下,再按照主键值进行排序。插入数据时是需要往 B+ 树中插入记录的,当二级索引出现多个相同的时,此时该如何插入呢?索引引入了主键,当二级索引相同的时候,根据主键的升序查找需要插入的位置。

一个页面至少容纳两条记录

其实这个最不难理解的,假设一个页只能容纳一条记录,那引入 B+ 树的意义又何在呢?直接查叶子节点不就好了,还费半天查目录项索引页,闲呀。

这是为什么存储可变字段,限制一个列最多存储字节的原因,然后让溢出字段存放在另一个页。这也是为什么我看很多表的创建会去使用 Dynamic 行格式的原因,如果发生溢出了直接把所有记录放到另一个页里,然后存的是那页的页号(或者说地址),我觉得就极大减少了容量,然后可以存更多的记录,当然其实 MySQL 设计者在省空间这一块算极致了。

二、回表的代价

回表的概念:就是说当使用二级索引的时候,无法从二级索引中获取查询的全部数据,得从二级索引中得到主键值然后再从聚簇索引中查找所需数据,这一个需要回到聚簇索引的过程叫做回表。

需要执行回表操作的记录越多,使用二级索引进行查询的效率也就越低,某些查询中宁愿使用全表扫描也不适用二级索引。比如:假设 key1 值在 ‘a’~‘c’ 之间的用户记录数量占所有记录的大多数,如果使用 key1 这个字段对应的二级索引,则会有大量的 id 值需要进行回表操作,这还不如直接进行全表扫描呢。

也就是说需要执行回表的操作越多,就会越倾向于使用全表扫描,反之则倾向于使用二级索引+回表的方式。而 limit 可以限制查询的记录数,这一操作可能使查询更倾向于二级索引+回表的方式。

对于需要对结果进行排序的查询,如果在采用二级索引执行查询时需要执行回表操作的记录特别多,也倾向于使用全表扫描 + 文件排序的方式进行排序。比如下面的这个查询语句:
select * from single_table order by key1
由于查询的列表是 * ,如果使用二级索引+回表的方式进行排序,则需要对所有的二级索引记录执行回表操作。这种操作的成本还不如直接遍历聚簇索引然后再进行文件排序低,所以查询优化器会倾向于使用全表扫描的方式执行查询,然后对文本进行排序。
但是如果添加了 limit 关键字,如下:
select * from single_table order by key1 limit 10
这个查询需要执行的回表操作的记录特别少,查询优化器就会倾向于使用 二级索引 + 回表的方式来执行。

三、更好的使用索引

  1. 只为用于搜索、排序或分组的列进行创建索引;
  2. 考虑索引列中不重复值的个数,即考虑回表的代价,如果某索引列的重复值太多,那会引起大量的回表操作,从而索引的效率会大大降低。
  3. 索引列的类型尽量小,让目录项节点的索引页可以存放更多的记录,也是一种预防索引树变高;
  4. 为列前缀建立索引。避免字符串太长,降低了索引的占用空间,但是注意:这种方式的排序不会走这个索引。如下面这样创建:
    alter table single_table add index idx_key1(10));
  5. 覆盖索引:即使用该二级索引我们就可以查询到自己想要的数据,而不需要进行回表,减少了索引的代价。最典型的就是通过二级索引查询主键,即不用进行回表
  6. 让索引列以列名的形式单独出现在搜索条件中,不然会导致索引失效。
  7. 主键最好是递增形式存放的,防止出现页分裂现象效率降低。

四、索引的代价

B+ 树索引在空间和时间上都有代价,所以没事儿别瞎建立索引。

空间:B+ 树索引的建立,占内存的。
时间:当执行增删操作的时候生成执行计划,而且还要给相关的二级索引进行增删,时间上也得付出代价滴。

参考:
《MySQL是怎样运行的》

题外话,一个疑问答案:为什么有了 binlog 记录操作日志,InnoDB 还要引入个 redolog 记录操作日志呢?

这还是和俩日志的作用有关系,binlog 是在 Server 层进行工作,记录的是逻辑操作,用于数据库的复制和恢复操作。而 redolog 的存在是在 InnoDB 存储引擎上工作的,它的存在是为了保障数据库的一致性和持久性。它记录的是物理操作,它在事务提交后会刷新到磁盘上。即使数据库崩溃了,redolog 也会进行数据恢复。

更多推荐

竞赛 基于深度学习的人脸专注度检测计算系统 - opencv python cnn

文章目录1前言2相关技术2.1CNN简介2.2人脸识别算法2.3专注检测原理2.4OpenCV3功能介绍3.1人脸录入功能3.2人脸识别3.3人脸专注度检测3.4识别记录4最后1前言🔥优质竞赛项目系列,今天要分享的是🚩基于深度学习的人脸专注度检测计算算法该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🥇学长这

slueth+zipkin 使用

目录背景过程(安装zipkinEureka提供方服务)ZipKin服务端安装微服务项目搭建1、搭建Eureka项目2、搭建消费者项目3、搭建提供者项目总结背景原因传统单机系统在使用过程中,如果某个请求响应过慢或是响应出错,开发人员可以清楚知道某个请求出了问题,查看日志可以定位到具体方法。但是在分布式系统中,倘若客户端一

MLAgents (0) Unity 安装及运行

1、下载ML-Agents下载地址GitHub-Unity-Technologies/ml-agents:TheUnityMachineLearningAgentsToolkit(ML-Agents)isanopen-sourceprojectthatenablesgamesandsimulationstoservea

拼多多app商品详情原数据API接口【详情页优惠券数据】APP端商品详情数据

拼多多app商品详情原数据API接口可以获取拼多多平台上某个商品的详细信息,包括商品标题、价格、图片、规格、参数、店铺信息等。要使用这个接口,需要先在拼多多平台注册一个开发者账号,并为每个拼多多应用注册一个应用程序键(AppKey)。然后需要下载拼多多API的SDK并掌握基本的API基础知识和调用。通过这个接口获取到的

RP9-0 快捷键与注意

1.快捷键.或者ctrl+.可以快速预览按住空格,鼠标就会变成手ctr+9回到页面原点2.注意有的动作要元件先获取焦点有的动作要元件先获取焦点文本输入框中的值要用.text截图工具SnipasteDownloadsSnipaste-截图+贴图快速吸取颜色C键,按住shift可以在RGB和HEX间切换腦圖:Xmind思维

Java版本spring cloud + spring boot企业电子招投标系统源代码

项目说明随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要求;通过电子化平台提高招投标工作的公开性和透明性;通过电子化招投标,使得招标采购的质量更高、速度

【面试题】——Java基础篇(35题)

文章目录1.八大基本数据类型分类2.重写和重载的区别3.int和integer区别4.Java的关键字5.什么是自动装箱和拆箱?6.什么是Java的多态性?7.接口和抽象类的区别?8.Java中如何处理异常?9.Java中的final关键字有什么作用?10.什么是Java的序列化和反序列化?11.Java中的Strin

下一个时代的船舵,李彦宏握住AI原生应用

相信大家都能感觉到,科技企业和开发者们正在积极转动航向,投身汹涌澎湃的大模型浪潮。越来越多基于大模型的AI应用和插件被推出,但从整体比例上看,AI原生应用的数量规模,远算不上百花齐放。可以回想一下历史上的技术革命,所有科技成果进入生活,靠的是一大群人充分释放智慧和想象力。电气化时代,商场里摆满了让人眼花缭乱的家用电器,

睿趣科技:新手商家如何做好抖音店铺

抖音,作为全球热门的社交媒体平台之一,不仅仅是分享有趣视频的地方,也是许多商家拓展业务的黄金平台。对于新手商家来说,如何在抖音上建立一个成功的店铺是一项重要的任务。以下是一些关于如何做好抖音店铺的建议。明确你的目标和定位:在开设抖音店铺之前,首先要明确你的目标和定位。你要销售什么样的产品或提供什么样的服务?你的目标客户

JVM 篇

目录一、知识点汇总二、知识点详解2.1JVM的主要组成部分及其作用2.2JVM内存模型2.3堆与栈的区别2.4JVM加载class文件的原理机制2.5类的生命周期2.6Java对象结构2.7Java对象创建过程2.8指针碰撞2.9空闲列表2.10TLAB+CAS2.11说说对象内存分配2.12什么是标量与聚合量?2.1

OpenCV自学笔记十六:直方图处理

在OpenCV中,直方图(Histogram)是用于表示图像中像素强度分布的一种统计工具。它可以帮助我们了解图像的亮度、对比度、色彩分布等信息。OpenCV提供了一个函数`cv2.calcHist()`,用于计算图像的直方图。该函数接受图像数组和一些参数,例如要计算的通道数、区间的数量等。它返回一个表示直方图的一维数组

热文推荐