索引、索引失效、索引的存储

news2024/11/25 13:48:59

文章目录

    • 1.索引种类
    • 2.创建索引注意点
    • 3.索引失效的情况
    • 4.为什么索引使用B+树存储
      • (1)如果使用数组来存储索引
      • (2)如果使用二叉查找树来存储索引
      • (3)如果使用平衡二叉查找树来存储索引
      • (4)如果使用B树来存储索引
        • 实例
      • (5)如果使用B+树来存储索引
        • B+树与B树的差异
        • B+树比B树的优势:
    • 5.Hash索引和 树索引的区别
    • 6.聚簇索引与非聚簇索引的区别
    • 7.回表
    • 8.覆盖索引
    • 9.最左匹配原则
      • 为什么不从最左开始查,就无法匹配呢?
    • 10.索引的下推优化
    • 11.explain详解

1.索引种类

MySQL中索引有四种:

  • 主键索引:不允许重复,不允许为NULL,一个表只能有一个
  • 唯一索引:不允许重复,允许为NULL,一个表可以有多个
  • 普通索引:允许重复,允许为NULL
  • 组合索引:多列值组成一个索引,用于组合搜索,效率大于索引合并

2.创建索引注意点

  • 索引应该建在查询应用频繁的字段
    在用于 where 判断、 order 排序和 join 的(on)字段上创建索引。
  • 索引的个数应该适量
    索引需要占用空间;更新时候也需要维护。
  • 区分度低的字段,例如性别,不要建索引。
    离散度太低的字段,扫描的行数降低的有限。
  • 频繁更新的值,不要作为主键或者索引
    维护索引文件需要成本;还会导致页分裂,IO次数增多。
  • 组合索引把散列性高(区分度高)的值放在前面
    为了满足最左前缀匹配原则
  • 创建组合索引,而不是修改单列索引。
    组合索引代替多个单列索引(对于单列索引,MySQL基本只能使用一个索引,所以经常使用多个条件查询时更适合使用组合索引)
  • 过长的字段,使用前缀索引。当字段值比较长的时候,建立索引会消耗很多的空间,搜索起来也会很慢。我们可以通过截取字段的前面一部分内容建立索引,这个就叫前缀索引。
  • 不建议用无序的值(例如身份证、UUID )作为索引
    当主键具有不确定性,会造成叶子节点频繁分裂,出现磁盘存储的碎片化

3.索引失效的情况

  • 查询条件包含or,可能导致索引失效
  • 如果字段类型是字符串,where时一定用引号括起来,否则会因为隐式类型转换,索引失效
  • like通配符可能导致索引失效
  • 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效
  • 在索引列上使用mysql的内置函数,索引失效。
  • 对索引列运算(如,+、-、*、/),索引失效。
  • 索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效。
  • 索引字段上使用is null, is not null,可能导致索引失效
  • 左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。
  • MySQL优化器估计使用全表扫描要比使用索引快,则不使用索引。

4.为什么索引使用B+树存储

https://mp.weixin.qq.com/s?__biz=MzUxODAzNDg4NQ==&mid=2247502168&idx=1&sn=ff63afcea1e8835fca3fe7a97e6922b4&scene=21#wechat_redirect

(1)如果使用数组来存储索引

索引数据最好能按顺序排列,这样可以使用「二分查找法」高效定位数据。

假设用数组存储索引,比如下面有一个排序的数组,如果要找出数字 3,最简单办法是遍历查询,时间复杂度是 O(n),查询效率不高。因为该数组是有序的,所以我们可以采用二分查找法。二分查找法每次都把查询的范围减半,时间复杂度降到了 O(log2n),但是每次查找都需要不断计算中间位置。
在这里插入图片描述
缺点:

  • 插入新元素的性能低
  • 使用二分查找时,每次查找都要不断计算中间的位置

(2)如果使用二叉查找树来存储索引

二叉查找树:一个节点的左子树的所有节点都小于这个节点,右子树的所有节点都大于这个节点,这样我们在查询数据时,不需要计算中间节点的位置了,只需将查找的数据与节点的数据进行比较。

优点:解决了连续结构插入新元素开销很大的问题,同时又保持着天然的二分结构
在这里插入图片描述
缺点:

  • 当每次插入的元素都是二叉查找树中最大的元素,二叉查找树就会退化成了一条链表,查找数据的时间复杂度变成了 O(n)
    在这里插入图片描述
  • 不能范围查询

(3)如果使用平衡二叉查找树来存储索引

在二叉查找树的基础上增加了一些条件约束:每个节点的左子树和右子树的高度差不能超过 1。也就是说节点的左子树和右子树仍然为平衡二叉树,这样查询操作的时间复杂度就会一直维持在 O(logn)。
在这里插入图片描述
在这里插入图片描述
缺点:

  • 虽然能保持查询操作的时间复杂度在O(logn),但本质上是二叉树,每个节点只能有 2 个子节点,节点个数越多,树的高度也会相应变高,这样就会增加磁盘的 I/O 次数,从而影响数据查询的效率

(4)如果使用B树来存储索引

为降低树的高度,后面就出来了 B 树,它不再限制一个节点只能有 2 个子节点,而是允每个节点最多有 M-1个数据和最多有M个子节点,超过这些要求的话,就会分裂节点,从而降低树的高度。M称为B树的阶,所以B树就是一个多叉树。

B树中每个节点都存放着索引和数据,数据遍布整个树结构,搜索可能在非叶子节点结束,最好的情况是O(1),下图是一个4阶B树。
在这里插入图片描述

实例

跟据关键字 {20、30、50、52、60、69、70},创建一棵3阶B树。非叶子节点至多有2个数据、3个子节点:
在这里插入图片描述
缺点:

  • B 树的每个节点都包含数据(索引+记录),而用户的记录数据的大小很可能远远超过了索引数据,这就需要花费更多的磁盘 I/O 操作次数来读到「有用的索引数据」。而且,在我们查询位于底层的某个节点(比如 A 记录)过程中,「非 A 记录节点」里的记录数据会从磁盘加载到内存,但是这些记录数据是没用的,我们只是想读取这些节点的索引数据来做比较查询,而「非 A 记录节点」里的记录数据对我们是没用的,这样不仅增多磁盘 I/O 操作次数,也占用内存资源。

(5)如果使用B+树来存储索引

B+ 树就是对 B 树做了一个升级,MySQL 中索引的数据结构就是采用了 B+ 树,B+ 树结构如下图:
在这里插入图片描述
在这里插入图片描述

B+树与B树的差异

  • 叶子节点(最底部的节点)才会存放实际数据(索引+记录),非叶子节点只会存放索引;
  • 所有索引都会在叶子节点出现,叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表
  • 非叶子节点的索引也会同时存在在子节点中,并且是在子节点中所有索引的最大(或最小)。
  • 非叶子节点中有多少个子节点,就有多少个索引;、、

B+树比B树的优势:

  • 是 B Tree 的变种,B Tree 能解决的问题,它都能解决。
    每个节点存储更多关键字。
  • 扫库、扫表能力更强
    如果我们要对表进行全表扫描,只需要遍历叶子节点就可以 了,不需要遍历整棵 B+Tree 拿到所有的数据。
  • B+Tree 的磁盘读写能力相对于 B Tree 来说更强,IO次数更少
    根节点和枝节点不保存数据区, 所以一个节点可以保存更多的关键字,一次磁盘加载的关键字更多,IO次数更少。
  • 排序能力更强
    因为叶子节点上有下一个数据区的指针,数据形成了链表。
  • 效率更加稳定
    B+Tree 永远是在叶子节点拿到数据,所以 IO 次数是稳定的

5.Hash索引和 树索引的区别

在这里插入图片描述

  • B+ 树可以进行范围查询,Hash 索引不能。
  • B+ 树支持联合索引的最左侧原则,Hash 索引不支持。
  • B+ 树支持 order by 排序,Hash 索引不支持。
  • Hash 索引在等值查询上比 B+ 树效率更高。
  • B+ 树使用 like 进行模糊查询的时候,like 后面(比如 % 开头)的话可以起到优化的作用,Hash 索引根本无法进行模糊查询。

6.聚簇索引与非聚簇索引的区别

聚集索引=聚簇索引
非聚集索引=辅助索引=二级索引=普通索引

聚集索引默认是主键,如果表中没有定义主键,InnoDB会选择一个唯一的非空索引代替,如果没有这样的索引,InnoDB会隐式地定义一个主键来作为聚集索引。一张表只允许存在一个聚集索引。因为真实数据的物理顺序只能有一种。
在这里插入图片描述

  • 一个表中只能拥有一个聚簇索引,而非聚簇索引一个表可以存在多个。
  • 聚簇索引,索引中键值的逻辑顺序决定了表中相应行的物理顺序;索引,索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
  • 聚簇索引:物理存储按照索引排序;非聚集索引:物理存储不按照索引排序;

7.回表

在InnoDB存储引擎里,利用辅助索引查询,先通过辅助索引找到主键索引的键值,再通过主键值查出主键索引里面没有符合要求的数据,它比基于主键索引的查询多扫描了一棵索引树,这个过程就叫回表。

例如: select * from user where name = ‘张三’;
例如:select * from user where name = ‘张三’;

8.覆盖索引

在辅助索引里面,不管是单列索引还是联合索引,如果 select 的数据列只用辅助索引中就能够取得,不用去查主键索引,这时候使用的索引就叫做覆盖索引,避免了回表。

比如,select name from user where name = ‘张三’;

在这里插入图片描述

9.最左匹配原则

在InnoDB的联合索引中,查询的时候只有匹配了左边的值之后,才能匹配下一个。

根据最左匹配原则,创建一个组合索引,如 (a1,a2,a3),相当于创建了(a1)、(a1,a2)和 (a1,a2,a3) 三个索引

为什么不从最左开始查,就无法匹配呢?

比如有一个user表,我们给 name 和 age 建立了一个组合索引。

ALTER TABLE user add INDEX comidx_name_phone (name,age);

组合索引在 B+Tree 中是复合的数据结构,它是按照从左到右的顺序来建立搜索树的 (name 在左边,age 在右边)。
在这里插入图片描述
这张图可以看出来,name 是有序的,age 是无序的。当 name 相等的时候, age 才是有序的。

这个时候我们使用 where name= ‘张三‘ and age = ‘20 ‘去查询数据的时候, B+Tree 会优先比较 name 来确定下一步应该搜索的方向,往左还是往右。如果 name 相同的时候再比较age。但是如果查询条件没有 name,就不知道下一步应该查哪个 节点,因为建立搜索树的时候 name 是第一个比较因子,所以就没用上索引。

10.索引的下推优化

索引条件下推优化(Index Condition Pushdown (ICP) )是MySQL5.6添加的,用于优化数据查询。

  • 不使用索引条件下推优化时存储引擎通过索引检索到数据,然后返回给MySQL Server,MySQL Server进行过滤条件的判断。
  • 当使用索引条件下推优化时,如果存在某些被索引的列的判断条件时,MySQL Server将这一部分判断条件下推给存储引擎,然后由存储引擎通过判断索引是否符合MySQL Server传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器。

例如一张表,建了一个联合索引(name, age),查询语句:

select * from t_user where name like '张%' and age=10;

由于name使用了范围查询,根据最左匹配原则:不使用ICP,引擎层查找到name like '张%'的数据,再由Server层去过滤age=10这个条件,这样一来,就回表了两次,浪费了联合索引的另外一个字段age。
在这里插入图片描述
但是,使用了索引下推优化,把where的条件放到了引擎层执行,直接根据name like ‘张%’ and age=10的条件进行过滤,减少了回表的次数。
在这里插入图片描述
索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少MySQL服务器从存储引擎接收数据的次数。

11.explain详解

https://www.cnblogs.com/annwyn/p/14432869.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

同为(TOWE)防雷产品助力福建移动南平分公司防雷改造

01 公司简介中国移动通信集团福建有限公司南平分公司属于福建移动地级分公司&#xff0c;所属行业为电信、广播电视和卫星传输服务。现已建成覆盖范围广、业务品种多、通信质量高的综合通信网络&#xff0c;具备行业领先的经营管理制度。移动通信大楼的综合防雷及地接系统&…

第八节 构造器和this关键字、封装

构造器的作用 定义在类中的&#xff0c;可以用于初始化一个类的对象&#xff0c;并返回对象的地址。 构造器的注意事项 1.任何类定义出来&#xff0c;默认就自带了无参数构造器&#xff0c;写不写都有。 2.一旦定义了有参数构造器&#xff0c;那么无参数构造器就没有了&#xf…

互联网人看一看,这些神器你用过哪些?

很多小伙伴在剪辑视频的过程中经常可以看到一些语音素材&#xff0c;经常刷视频的小伙伴也可以看到很多视频中经常出现一些AI合成的声音或者音效&#xff0c;这些配音可以给视频增添很多亮点&#xff01;那么大家都是怎么将文字转语音的呢&#xff1f;今天给大家分享5款非常专业…

【Git】Git常用命令及练习—Git环境配置

目录 一、Git环境配置 1.1基本配置 1.2为常用指令配置别名&#xff08;可选&#xff09; 1.3 解决GitBash乱码问题 二、Git命令详细操作 1.获取本地仓库 2.基础操作命令及练习 基础操作练习 3.分支命令及练习 开发中分支使用原则与流程 分支练习 &#x1f49f; 创作不…

Ubuntu20.04安装Cuckoo

参考链接&#xff1a; &#xff08;1&#xff09;【主要参考】http://www.wityx.com/post/134851_1_1.html &#xff08;2&#xff09;【主要参考】在Ubuntu18.04上搭建Cuckoo Sandbox2.0.7 https://www.jianshu.com/p/4dd6373fa206 &#xff08;3&#xff09;与Cuckoo的斗智斗…

Kafka入门(五)

下面聊聊Kafka常用命令 1、Topic管理命令 以topic&#xff1a;test_1为例 1.1、创建topic ./bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 3 --topic test_1参数说明&#xff1a; –bootstrap-server&#xff1a;…

【论文笔记】Decoupling Representation and Classifier for Long-Tailed Recognition

这一篇其实并不是提出什么新的东西&#xff0c;而且是做了点类似综述的技术调用实验。省流&#xff1a;T-normalization最好用 摘要 现状&#xff1a;Existing solutions usually involve class-balancing strategies, e.g. by loss re-weighting, data re-sampling, or tran…

【操作方法】windows防火墙添加出入站规则方法

【操作方法】windows防火墙添加出入站规则方法说明一、入站规则1.打开防火墙&#xff0c;点击“高级设置”2.点击“入站规则”后点击“新建规则”3.例3.1选择“端口”3.2添加需要放通的端口3.3选择操作动作为“允许连接”3.4选择应用区域&#xff0c;此处我选择所有区域二、出站…

Linux: malloc()的指向指针发生指向偏移后,释放前需要将指针指向复原。

Linux: malloc()的指向指针发生指向偏移后&#xff0c;释放前需要将指针指向复原。 #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <time…

A Contextual-Bandit Approach to Personalized News Article Recommendation-论文学习

A Contextual-Bandit Approach to Personalized News Article Recommendation-论文学习 github地址&#xff1a;bandit-learning 摘要 该算法根据用户和文章的上下文信息依次选择文章为用户服务&#xff0c;同时根据用户点击反馈调整其文章选择策略&#xff0c;以最大化用户…

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…

Qt音视频开发18-不同视频打开无缝切换

一、前言 在轮询视频的时候&#xff0c;通常都是需要将之前的视频全部关闭&#xff0c;然后打开下一组视频&#xff0c;在这个切换的过程中&#xff0c;如果是按照常规的做法&#xff0c;比如先关闭再打开新的视频&#xff0c;肯定会出现空白黑屏之类的过度空白区间&#xff0…

【解决办法】windows防火墙出入站规则放通telnet方法

【操作方法】windows防火墙出站规则放通telnet方法一、出站规则1.新建出站规则中选择“程序”2.选择路径&#xff0c;点击“下一页”3.选择“允许连接”4.选择所有区域二、入站规则注&#xff1a;打开防火墙添加出入站规则参考【操作方法】windows防火墙添加出入站规则方法 一、…

Learining C++ No.12【vector】

引言&#xff1a; 北京时间&#xff1a;2023/2/27/11:42&#xff0c;高数考试还在进行中&#xff0c;我充分意识到了学校的不高级&#xff0c;因为题目真的没什么意思&#xff0c;虽然挺平易近人&#xff0c;但是……&#xff0c;考试期间时间比较放松&#xff0c;所以不能耽误…

通过python技术获取甲流分布数据

近期&#xff0c;多地学校出现因甲流导致的班级停课&#xff0c;儿科甲流患者就诊量呈数倍增长。此轮甲流为何如此严重&#xff1f;感染甲流之后会出现哪些症状&#xff1f; 经过专家的介绍甲流之所以这么严重有这些原因导致的。一、疫情完全放开后很多孩子不戴口罩了&#x…

CData Drivers for Cassandra Crack

CData Drivers for Cassandra Crack Cassandra JDBC驱动程序允许用户连接Cassandra的实时数据。它允许从任何能够支持JDBC连接的应用程序直接连接。它将Java应用程序与实时Cassandra和NoSQL以及云服务和数据库连接起来。用户可以使用ApacheCassandra&#xff0c;因为在本例中&a…

微软新版必应gpt人工智能体验教程

大家好,我是雄雄,欢迎关注微信公众号:** 雄雄的小课堂 ** 现在是:2023年2月28日18:35:02 前言 前几天,发了一篇文章,主要介绍了如何申请新必应的内测名单,其实一共也就那几步,然后等着就行: 文章连接:new bing如何快速申请内测资格,从而体验人工智能? 今天,终于…

电商搜索入门

一、搜索用途通常一个电商平台里面的商品&#xff0c;少则几十万多则上千万甚至上亿的sku&#xff0c;在这么多的商品中&#xff0c;如何让用户可以快速查找到自己想要的商品&#xff0c;那么就需要用到搜索功能来实现。通过分析数据发现&#xff0c;接近40%的点击率是直接通过…

【Redis学习2】Redis常用数据结构与应用场景

Redis常用数据结构与应用场景 redis中存储数据是以key-value键值对的方式去存储的&#xff0c;其中key为string字符类型&#xff0c;value的数据类型可以是string(字符串)、list(列表)、hash(字典)、set(集合) 、 zset(有序集合)。 这5种数据类型在开发中可以应对大部分场景的…

「RISC-V Arch」RISC-V 规范结构

日期&#xff1a;20230228 规范分类 根据 RISC-V 设计哲学&#xff0c;其规范文档也是高度模块化的&#xff1a; ISA 规范&#xff08;2 篇&#xff09; 非特权规范特权规范 非 ISA 规范&#xff08;6篇&#xff09; Trace规范ABI 规范外部调试规范PLIC 规范SBI 规范UEFI 协…