【面试八股总结】MySQL索引(二):B+树数据结构、索引使用场景、索引优化、索引失效

参考资料:小林coding、阿秀

一、为什么InnoDB采用B+树作为索引数据结构?

        B 树是一个自平衡多路搜索树,每一个节点最多可以包括 M 个子节点,M 称为 B 树的阶,所以 B 树就是一个多叉树。

        B+ 树与 B 树的差异:

  • 叶子节点(最底部的节点)才会存放实际数据(索引+记录),非叶子节点只会存放索引;

  • 所有索引都会在叶子节点出现,叶子节点之间构成一个有序链表;

  • 非叶子节点的索引也会同时存在在子节点中,并且是在子节点中所有索引的最大(或最小)。

  • 非叶子节点中有多少个子节点,就有多少个索引;

MySQL中B+树结构:

1、B+Tree vs B Tree

B+Tree 只在叶子节点存储数据,而 B 树 的非叶子节点也要存储数据,所以 B+Tree 的单个节点的数据量更小,在相同的磁盘 I/O 次数下,就能查询更多的节点。

另外,B+Tree 叶子节点采用的是双链表连接,适合 MySQL 中常见的基于范围的顺序查找,而 B 树无法做到这一点。

2、B+Tree vs 二叉树

对于有 N 个叶子节点的 B+Tree,其搜索复杂度为O(logdN),其中 d 表示节点允许的最大子节点个数为 d 个。

在实际的应用当中, d 值是大于100的,这样就保证了,即使数据达到千万级别时,B+Tree 的高度依然维持在 3~4 层左右,也就是说一次数据查询操作只需要做 3~4 次的磁盘 I/O 操作就能查询到目标数据。

而二叉树的每个父节点的儿子节点个数只能是 2 个,意味着其搜索复杂度为 O(logN),这已经比 B+Tree 高出不少,因此二叉树检索到目标数据所经历的磁盘 I/O 次数要更多。

3、B+Tree vs Hash

Hash 在做等值查询的时候效率很快,时间复杂度为 O(1)。

但是 Hash 表不适合做范围查询,它更适合做等值的查询,这也是 B+Tree 索引要比 Hash 表索引有着更广泛的适用场景的原因。

二、索引适用场景

首先,先明确为什么需要使用索引?
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
  • 帮助服务器避免排序和临时表
  • 将随机IO变为顺序IO
  • 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义
在此基础上,思考什么场景下适合使用索引?
  • 字段有唯一性限制的,比如商品编码;
  • 经常用于 WHERE 查询条件的字段,这样能够提高整个表的查询速度,如果查询条件不是一个字段,可以建立联合索引。
  • 经常用于 GROUP BY 和 ORDER BY 的字段,这样在查询的时候就不需要再去做一次排序了,因为我们都已经知道了建立索引之后在 B+Tree 中的记录都是排序好的。
什么时候不需要创建索引?
  • WHERE 条件,GROUP BYORDER BY 里用不到的字段,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的,因为索引是会占用物理空间的。
  • 字段中存在大量重复数据,不需要创建索引,比如性别字段,只有男女,如果数据库表中,男女的记录分布均匀,那么无论搜索哪个值都可能得到一半的数据。在这些情况下,还不如不要索引,因为 MySQL 还有一个查询优化器,查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。
  • 表数据太少的时候,不需要创建索引;
  • 经常更新的字段不用创建索引,比如不要对电商项目的用户余额建立索引,因为索引字段频繁修改,由于要维护 B+Tree的有序性,那么就需要频繁的重建索引,这个过程是会影响数据库性能的。

三、索引优化

1. 前缀索引优化

        使用某个字段中字符串的前几个字符建立索引,减小索引字段大小,增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。

不过,前缀索引有一定的局限性,例如:

  • order by 就无法使用前缀索引;
  • 无法把前缀索引用作覆盖索引;

2. 覆盖索引优化

        覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表的操作,减少大量的 I/O 操作。

3. 主键索引最好是自增的

        InnoDB 创建主键索引默认为聚簇索引,数据被存放在了 B+Tree 的叶子节点上。也就是说,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。

        如果使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。

        如果使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率

4. 索引最好设置为 NOT NULL

为了更好的利用索引,索引列要设置为 NOT NULL 约束。有两个原因:

  • 索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,更加难以优化,因为可为 NULL 的列会使索引、索引统计和值比较都更复杂,比如进行索引统计时,count 会省略值为NULL 的行。

  • NULL 值是一个没意义的值,但会占用物理空间,带来存储空间的问题,因为 InnoDB 存储记录的时候,如果表中存在允许为 NULL 的字段,那么行格式中至少会用 1 字节空间存储 NULL 值列表,如下图的紫色部分:

四、索引失效

发生索引失效的情况:

  • 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;
  • 当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效;
  • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/677295.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【UE5 刺客信条动态地面复刻】实现无界地面01:动态生成

为了快速上手UE5,开启了《复刻刺客信条动态地面》的技术篇章,最终希望复刻刺客信条等待界面的效果,这个效果大体上包括: 基础的地面随着任务走动消失和出现的基础效果地板的Bloom和竖起的面片辉光效果 既然是新手,&am…

CSS学习笔记之高级教程(五)

23、CSS 媒体查询 - 实例 /* 如果屏幕尺寸超过 600 像素&#xff0c;把 <div> 的字体大小设置为 80 像素 */ media screen and (min-width: 600px) {div.example {font-size: 80px;} }/* 如果屏幕大小为 600px 或更小&#xff0c;把 <div> 的字体大小设置为 30px …

器利而事善——datagrip 的安装以及简单使用

一&#xff0c;安装 下载&#xff1a;直接到官网下载即可&#xff0c; 破解&#xff1a;这是破解连接&#xff1a;https://pan.baidu.com/s/11BgOMp4Z9ddBrXwCVhwBng &#xff0c;提取码&#xff1a;abcd&#xff1b; 下载后&#xff0c;选择倒数第三个文件&#xff0c;打开da…

【ZZULI数据结构实验四】:C语言排序算法大比拼

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

洛谷 P10566 「Daily OI Round 4」Analysis 题解

先弄个 ASCII 码表&#xff1a; 分析 很明显&#xff0c;想要节省时间&#xff0c;就要把这些字符转换成和它们的 ASCII 值最接近的大写字母。 通过 ASCII 码表&#xff0c;很容易就可以发现&#xff1a; ASCII 值与数字最接近的大写字母是 A \texttt A A。ASCII 值与小写…

切片的MBTiles格式和XYZ格式

MBTiles 和XYZ是两种经常使用的切片格式&#xff0c;尤其是各类下载器下载在线地图时经常使用这种格式。 MBTiles 是一种用于存储地图切片&#xff08;tileset&#xff09;的文件格式&#xff0c;通常用于地图的存储和传输。该格式由 Mapbox 开发&#xff0c;旨在简化大规模栅格…

TensorFlow库详解:Python中的深度学习框架

引言 TensorFlow是由Google Brain团队开发的开源机器学习库&#xff0c;用于各种复杂的数学计算&#xff0c;特别是涉及深度学习的计算。它提供了大量工具和资源&#xff0c;用于构建和训练机器学习模型。TensorFlow因其强大的功能和灵活性&#xff0c;在机器学习和深度学习领…

IGraph使用实例——贝尔曼-福特算法(求解单源最短路径)

1 概述 本文中求解最短路径使用的方法是igraph中基于贝尔曼-福特算法&#xff08;Bellman-Ford算法&#xff09;。Bellman-Ford算法是一种用于在加权图中找到从单个源点到所有其他顶点的最短路径的算法。这个算法可以处理包含负权重边的图&#xff0c;但不能处理有负权重循环的…

CTFHUB-技能树-web-web前置技能-HTTP协议全

目录 1.请求方式 2.302跳转 3.Cookie 4.基础认证 5.响应包源码 1.请求方式 curl -v -X http://challenge-3022c877a8dcedeb.sandbox.ctfhub.com:10800/index.php 2.302跳转 参考链接&#xff1a;http://t.csdnimg.cn/aqdNG 301——永久性重定向。该状态码表示请求的资源已…

Springboot vue elementui 前后端分离 事故灾害案例管理系统

源码链接 系统演示:https://pan.baidu.com/s/1hZQ25cpI-B4keFsZdlzimg?pwdgw48

构造,CF862C. Mahmoud and Ehab and the xor

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 862C - Codeforces 二、解题报告 1、思路分析 非常松的一道构造题目 我们只需让最终的异或和为x即可 下面给出个人一种构造方式&#xff1a; 先选1~N-3&#xff0c;然后令o (1 << 17) …

树莓集团领航:园区运营新标杆

在当今经济飞速发展的时代&#xff0c;产业园区作为推动地方经济增长、优化产业布局的重要平台&#xff0c;其运营和管理水平至关重要。树莓集团&#xff0c;作为园区运营的政企典范&#xff0c;凭借其专业的运营能力和卓越的服务品质&#xff0c;赢得了业界的广泛赞誉。 树莓…

大模型 vs 数据资产,谁才是真正的BOSS?

大数据产业创新服务媒体 ——聚焦数据 改变商业 在数字化时代的浪潮中&#xff0c;数据资产管理已成为企业战略中不可或缺的一环。随着数据量的激增&#xff0c;如何有效管理、利用这些数据&#xff0c;提炼其价值&#xff0c;成为了摆在每个组织面前的重大挑战。在这个背景下…

dataframe元组和字典操作

这是一个测试文件&#xff0c;今天发现一些有意思的语法&#xff0c; 首先字典是可以加入元组的 AA {"a":2,"b":23,"c":(1,2,3)} print(AA)结果如下 example1 import pandas as pd data pd.DataFrame(data {"a":(-1,-2,-3),&quo…

大数据—元数据管理

在大数据环境中&#xff0c;元数据管理是确保数据资产有效利用和治理的关键组成部分。元数据是描述数据的数据&#xff0c;它提供了关于数据集的上下文信息&#xff0c;包括数据的来源、格式、结构、关系、质量、处理历史和使用方式等。有效的元数据管理有助于提高数据的可发现…

HTML+CSS+JS 倒计时动画效果

效果演示 实现了一个倒计时动画效果,包括数字区域和倒计时结束区域。数字区域显示倒计时数字,数字进入时有动画效果,数字离开时也有动画效果。倒计时结束后,数字区域隐藏,倒计时结束区域显示,显示时也有动画效果。用户可以点击重新开始按钮重新开始倒计时。 Code <!D…

上海亚商投顾:创业板指震荡收涨 超70家ST股跌停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡震荡&#xff0c;创业板指走势稍强&#xff0c;盘中一度涨超1%&#xff0c;黄白二线分化严重。算…

【Spring框架全系列】SpringBoot_3种配置文件_yml语法_多环境开发配置(详细)

文章目录 1.三种配置文件2. yaml语法2.1 yaml语法规则2.2 yaml数组数据2.3 yaml数据读取 3. 多环境开发配置 1.三种配置文件 问题导入 框架常见的配置文件有哪几种形式&#xff1f; 比如&#xff1a; jdbc.properties spring.properties 如果每个技术或者框架都要这么写一个配…

404错误页面源码,简单实用的html错误页面模板

源码描述 小编精心准备一款404错误页面源码&#xff0c;简单实用的html错误页面模板&#xff0c;简单大气的页面布局&#xff0c;可以使用到不同的网站中&#xff0c;相信大家一定会喜欢的 效果预览 源码下载 https://www.qqmu.com/3375.html

Linux 命令 | 运维必学,用户和组管理命令实践集锦

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 大家好&#xff0c;我是一个正在向全栈工程师(SecDevOps)前进的计算机技术爱好者 作者微信&#xff1a;WeiyiGeeker公众号/星球&#xff1a;全栈工程师修炼指南主页博客: https://weiyigeek.top -…