第15章:索引的数据结构

news2024/11/24 14:38:44

一、为什么使用索引

1.索引是存储引擎用于快速找到记录的一种数据结构。相当于一本书的目录。在进行数据查找时,首先查看查询条件是否命中某条索引,符合则通过索引查找相关数据。如果不符合则需要全表扫描,一条一条查找记录,直到找到与条件符合的记录。

2.创建索引减少磁盘的I/O的次数,加快查询速度。

二、索引的优缺点

1.索引概述

①索引是MySQL高效获取数据的数据结构

②索引的本质:索引是数据结构,排好序的快速查找的数据结构

③索引是在存储引擎实现的,每种存储引擎不一定支持所有的索引类型。存储引擎定义表的最大索引数最大索引长度

2.索引优点

①索引提高数据检索的效率,降低数据库的IO成本

②通过创建唯一索引,保证数据库表每一行的数据唯一性

加速表和表之间的连接,对于有依赖关系的子表和父表联合查询时,可以提高查询速度

④使用分组和排序子句进行查询数据时,显著减少查询分组和排序的时间,降低CPU消耗

3.索引缺点

①创建索引和维护索引耗费时间,随着数据量增加,所耗费的时间增加

②索引占磁盘空间,存储在磁盘上

③索引提高查询速度,同时降低更新表的速度,在表中的数据增加,删除,修改,索引动态维护,降低数据的维护速度。

4.索引的提示

索引提高查询的速度,会影响插入的速度。这种情况下,最好的办法是先删除表中的索引,然后插入数据,插入完成再创建索引

三、InnoDB索引的推演

3.1没有索引情况下查找

3.1.1.在一个页查找

①主键查找

select *
from employees
where employee_id=101;

 在页目录使用二分法快速定位到对应的槽,然后再遍历槽对应分组的记录,快速找到指定的记录

②其他列作为条件(非主键的列)

select *
from employees
where last_name='Abel';

 只能从最小记录开始依次遍历单链表中的每条记录,判断是否符合条件,效率低。

3.1.2.在很多页查找

①定义到记录所在的页

②从所在的页查找对应的记录

没有索引情况下,不论根据主键还是其他列,只能从第一页沿着双向链表一直往下找,在每个页根据上面的查找方法查找指定的记录。非常耗时,所以索引来了。

3.2设计索引

建一个表

 ①index_demo表的行格式示意图

record_type:0是普通记录,2是最小记录,3是最大记录

next_record记录下一条数据的地址

②把一些记录存放到表里的示意图

3.2.1简单的索引设计方案

问题:想快速定位到需要查找的数据在哪些数据页,可以为数据页建立一个目录:

①所有数据页里面的记录的主键是递增的

 ②为数据页建立目录:当前页的主键最小值key,当前页号page_no

 

此时把目录项在物理存储器连续存储,实现主键快速查找某条记录的功能。

比如:查找主键20

①先从目录项根据二分法快速确定主键值为20在目录3中(12<20<209)

②在页中查找记录方法根据主键值二分法查找具体的记录

3.2.2InnoDB中的索引方案

①迭代1次:目录项记录的页,采用单向链表实现,便于增加和删除

 

record_type=1表示存放的是目录项

record_type=0 表示存放的是普通记录

目录项记录和普通用户记录的相同点:都会为主键值生成Page Directory(页目录),按照主键值进行查找时使用二分法加快查询速度。

比如:查找主键20

先从页30中通过二分法快速定位到对应目录项,因为(12<20<209),定位到页9

从页9使用二分法定位到主键值为20的用户记录

②迭代2次:多个目录项记录的页,双向链表

假设目录项记录的页最大记录是4,现在新添加的记录,所以要生成新的目录项的页

比如:查找主键20

确定目录项记录页,现在目录项页30和页32,页30的主键值范围是[1,320),页32是不小于320,所以在页30

通过目录项记录页根据二分法查找出对应的目录项,定位页9

在页9通过二分法定位到主键20的用户记录

③迭代3次:目录项记录页的目录页,大目录嵌套小目录

 生成存储高级目录项的页33,这个页中的两条记录代表页30和页32。

④这个结构就是B+树

B+树都不会超过4层,通过主键值查找某条记录最多需要4个页面内的查找。(3个目录项页,1个用户记录页),每个页面有page Directory页目录,可以通过二分法快速定位记录。

假设:普通数据页:100条用户记录 目录项记录页:1000条目录项记录

如果B+树只有1层,只有1个存放用户记录的节点,最多能存放 100 条记录。

如果B+树有2层,最多能存放 1000×100=10,0000 条记录。

如果B+树有3层,最多能存放 1000×1000×100=1,0000,0000 条记录。

如果B+树有4层,最多能存放 1000×1000×1000×100=1000,0000,0000 条记录

3.3常见索引的概念

3.3.1聚簇索引:主键构建的B+树

概念:

聚簇索引是一种数据存储方式,所有的用户记录都在叶子节点,索引即数据,数据即索引。

聚簇表示数据行和相邻的键值聚簇的存储在一起。InnoDB存储引擎会自动创建聚簇索引

特点:

①页内记录按照主键的大小排序成一个单向链表,有序的

②存放记录的页按照主键值大小顺序排成一个双向链表

③存放目录项记录的页按照主键值顺序排成一个双向链表

④B+树的叶子节点存储的是完整的用户记录

优点:

①数据访问快,聚簇索引将索引和数据保存在同一个B+树中。B+树的叶子节点就是完整的用户记录

②因为按照主键大小排序成一个单链表,排序查找和范围查找速度快

③查找范围的数据时,数据紧密相连,节省了大量IO操作

缺点:

①插入速度严重依赖插入顺序,否则会出现页的分裂,影响性能。因此InnoDB表,定义一个自增的ID列作为主键

②更新主键的代价很高。会导致更新行的移动。对于InnoDB表,定义主键不可更新

③二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

限制:

①InnoDB支持聚簇索引,MyISAM不支持聚簇索引

②每个表只能有一个聚簇索引,该表的主键

③没有定义主键,InnoDB选择非空的唯一索引代替。没有的话,InnoDB隐式定义主键

④InnoDB的键尽量选择有序的id,不建议UUID,MD5,HASH,字符串作为主键

3.3.2非聚簇索引(二级索引,辅助索引):非主键构建的B+树

概念:

如果使用非主键字段进行查找,可以多建几棵B+树,每个树采用不同的排序规则。比如c2的列,进行查找。按照非主键列建立的B+树需要一次回表操作能定位到完整的用户记录,这种B+树是二级索引。

 叶子节点,数据页里面的数据按照c2的大小排序成单链表。用户记录不完整,存c2和主键项。

回表:(回聚簇索引)

根据c2的列(非主键列)大小排序的B+树,只能找到查找记录对应的主键值,二级索引没有完整的用户记录,所以需要到聚簇索引根据查找出的主键值再查一遍。这个过程就是回表。所以从非主键列条件查找一条记录需要2棵B+树

为什么要回表操作,把完整的用户记录存放到二级索引的叶子节点不行吗

太占内存空间。冗余大

一张表有1个聚簇索引和多个非聚簇索引。

 3.3.3联合索引:多个列作为排序规则,c2,c3组合

概念:

①把各个记录和页按照c2进行排序

②在c2列相同情况下,采用c3进行排序。

③本质上是二级索引,需要回表操作

④叶子节点用户记录是c2,c3和主键c1构成

3.4InnoDB的B+树索引的注意事项

3.4.1根页面内存位置万年不动

B+树的形成过程:

①当创建一个表的时候,底层为这个索引创建一个根节点,此时没有目录项和用户记录

②向表中插入数据时,先存储在根节点

③当根节点空间用满时(假设3条),此时根节点成为目录页复制一个新页(页a)

④再插入一个数据时,通过页分裂操作,得到页b。

⑤随着插入操作,叶子节点变多,目录项空间满了。此时根节点复制一个新目录页a

⑥当进行插入的时候,会把目录项存放到目录页b

当InnoDB用到这个索引的时候,都会从固定的地址找到这个根节点的页号,从而访问这个索引。

3.4.2内节点中目录项记录的唯一性(除了非叶子节点)

①B+树索引的内节点目录项是索引列+页号。假设一个表的数据是

 构建的二级索引B+树,如过插入一条数据 (8,1,’c’),就不知道是插入页4还是页5了。造成了目录项记录不唯一

②解决方法是目录项加入主键:索引列+主键值+页号

 3.4.3一个页面最少存储2条记录

四、MyISAM中的索引方案:B-Tree索引

1.介绍

MyISAM引擎使用B+Tree作为索引结构,但是叶子节点的data域存放的是数据记录的地址

2.原理

InnoDB中索引就是数据。但在MyISAM中索引和数据分开存储,非聚簇索引

 

①数据文件:用户记录的插入顺序单独储存的一个文件。不分页。不按照主键大小排序。不能使用二分法查找

②索引文件:存放索引信息的,为表中的主键创建一个索引。叶子节点存放的是主键值+数据记录的地址

3.MyISAM和InnoDB的对比

MyISAM的索引方式是“非聚簇的”,InnoDB包含1个聚簇索引

①在InnoDB中根据主键值对聚簇索引进行一次查找就能找到对应的记录。在MyISAM(非聚簇,二级索引)需要一次回表操作。

②InnoDB数据文件就是索引文件,索引即数据。但是MyISAM的数据文件和索引文件是分离的,索引文件保存的是数据的地址

③InnoDB的非聚簇索引的data域存放的是主键的值,而MyISAM存放的是记录的地址。

④MyISAM的回表十分迅速,拿着地址直接找数据。但InnoDB通过获取主键后在聚簇索引查找记录。

⑤InnoDB要求表必须有主键,MyISAM可以没有。在InnoDB如果没有指定,MySQL自动选择一个非空且唯一做主键。如果不存在这种类型,MySQL自动为InnoDB隐含字段做主键。

五、索引的代价

空间上代价

每次建立索引都是建立B+树,每一棵B+树的节点都是数据页。一个数据页默认16KB,许多数据页组成,就是一大片存储空间

时间上代价

每次对表中的数据增、删、改需要修改B+树的索引。B+树的节点按照索引列的值从小到大顺序排序双向链表。存储引擎需要额外的时间进行一些记录移位,页面分裂、页面回收等操作来维护好节点和记录的排序。

六、MySQL为什么选择B+树

选择标准

能让索引的数据结构尽量减少磁盘的I/O操作次数。索引是存储在外部磁盘上的,只能逐一加载到内存。MySQL衡量查询效率标准就是磁盘IO次数

1.Hash结构:数组+链表

 

问题1:为什么Hash效率高,索引结构使用的是树形呢?

①Hash索引仅能满足等于,不等于,in的等值查询。如果是范围查询,时间复杂度是O(n),树形是有序的,保持高效率

②Hash索引的缺陷是没有顺序的,order by 排序时要重新排序

③对于联合索引,Hash值是一起计算的,无法对单独一个键或几个索引键查询

④Hash索引不适合在重复值多的列上,比如性别,年龄。因为遇到Hash冲突时,需要遍历桶中的行指针进行比较,找到查询关键字非常耗时。

问题2:什么是InnoDB自适应的Hash索引?

如果某个数据经常被访问,当满足一定条件,当前的数据页地址就会放到Hash表中,当下次查询时,直接到找个页的位置。B+树也有了Hash的优点

 

 2.二叉搜索树

磁盘的IO次数跟索引树的高度是相关的。

为了提高查询效率,就需要 减少磁盘IO数 。为了减少磁盘IO的次数,就需要尽量 降低树的高度 ,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好。

3.AVL树:平衡二叉树

针对同样的数据,如果我们把二叉树改成 M 叉树 (M>2)呢?当 M=3 时,同样的 31 个节点可以由下面的三叉树来进行存储:

 4.B树:非叶子节点存放的也是数据

 

查找的关键字是 9步骤:

①与根节点的关键字 (17,35)进行比较,9 小于 17 那么得到指针 P1;

②按照指针 P1 找到磁盘块 2,关键字为(8,12),因为 9 在 8 和 12 之间,所以我们得到指针 P2;

③按照指针 P2 找到磁盘块 6,关键字为(9,10),然后我们找到了关键字 9。

5.B+

 

 

 

问题1:B+树和B树的区别

①B+树有K个关键字就有K个孩子,B树有K个关键字,孩子是K+1

②B+树中只有叶子节点存数据,B树叶子节点和非叶子节点都存放数据

③B+树所有的关键字都在叶子节点出现,构成一个有序链表,按照关键字从小到大排序。

问题2:为什么B+树非叶子节点不存放数据,好处是什么

①B+树查询效率更稳定:B+树访问到叶子节点才有数据,但是B树非叶子节点和叶子节点都有数据,查询不稳定

②B+树查询效率更高:B+树比B树更矮胖。查询IO次数少,B+树存储更多的节点关键字

③在查询范围上,B+树效率比B树高。B+树的数据都在叶子节点上,而且数据递增的。B树需要遍历才能完成查找,效率低。

问题3:为了减少IO,索引树会一次性加载吗?

①数据库索引是存储在磁盘上的,如果数据量很大。索引会很大,超过几个G

②当利用索引时,不能把几个G的索引加载到内存。逐一加载到每一个磁盘页,磁盘页对应着索引树的节点。

问题4:B+树的存储能力如何?为何说一般查找行记录,最多只需1~3次磁盘IO

InnoDB的存储引擎中页的大小为16KB,一个页大概存储1000个键值。深度为3的B+可以维护10亿条记录

实际情况每个节点不可能填充满,因此数据库中2-4层(包含根节点),因为根节点就在内存,所以只需1-3次磁盘的IO操作。

问题5:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?

(回答B+树的优点)

①B+树查询效率更稳定:B+树访问到叶子节点才有数据,但是B树非叶子节点和叶子节点都有数据,查询不稳定

②B+树查询效率更高:B+树比B树更矮胖。查询IO次数少,B+树存储更多的节点关键字

③在查询范围上,B+树效率比B树高。B+树的数据都在叶子节点上,而且数据递增的。B树需要遍历才能完成查找,效率低。

问题6:Hash 索引与 B+ 树索引的区别

①Hash索引不能范围查找,B+树可以。Hash数据是无序,B+叶子节点是有序链表

②Hash索引的缺陷是没有顺序的,order by 排序时要重新排序。B+叶子节点是有序链表

③对于联合索引,Hash值是一起计算的,无法对单独一个键或几个索引键查询,B+树可以

④InnoDB不支持哈希索引

问题7:Hash索引与 B+ 树索引是在建索引的时候手动指定的吗?

根据MySQL的存储引擎决定的。

InnoDB和MyISAM存储引擎是B+树索引,但InnoDB提供自适应的Hash

Memory/Heap和NDB存储引擎,可以选择Hash索引

 

 

 

 

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

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

相关文章

Layui源码解读之define函数

一、layui.define 用法 layui.define([mods], callback) 通过layui.define该方法可在新的 JS 文件中定义一个 layui 模块。 mods 是可选的&#xff0c;用于声明该模块所依赖的模块。callback 为模块加载完毕的回调函数&#xff0c;它返回一个 exports 参数&#xff0c;用于输出…

鸿蒙App开发选择Java还是JavaScript?

众所周知&#xff0c; Java和 JavaScript是两种编程语言&#xff0c;这两种语言在不同的环境中都有许多用途。在鸿蒙 App开发中&#xff0c; Java和 JavaScript是两种常见的编程语言&#xff0c;它们都具有广泛的应用&#xff0c;并且都有其独特的优势。下面我们将就这两种编程…

LiveGBS国标GB/T28181国标平台功能-电子地图移动位置订阅mobileposition地图定位GPS轨迹坐标位置获取redis获取位置

LiveGBS国标GB/T28181国标平台功能-电子地图移动位置订阅mobileposition地图定位GPS轨迹坐标位置获取redis获取位置 1、位置订阅1.1、国标设备编辑1.2、选择设备开启位置订阅1.3、全局开启位置订阅1.4、通过目录订阅获取位置(少数情况) 2、经纬度信息查询2.1、访问接口获取2.1.…

详解iPaaS与RPA的区别及各自的应用场景

随着企业数字化转型的加速&#xff0c;业务系统集成和自动化流程成为关键议题。本文旨在探讨iPaaS&#xff08;Integration Platform as a Service&#xff09;与RPA&#xff08;Robotic Process Automation&#xff09;在业务系统集成方面的区别&#xff0c;它们各自的用途和适…

python数据分析案例——零售商店电子销售订单分析

一、项目背景 通过"扫描"零售商店电子销售点个别产品的条形码而获得的消费品销售的详细数据。 这些数据提供了有关所售商品的数量、特征和价值以及价格的详细信息。 二、数据来源 https://www.kaggle.com/marian447/retail-store-sales-transactions 三、提出问…

windows11@OpenWith@选择文件打开方式导致卡死@windows11任务栏显示秒

文章目录 OpenWith选择文件打开方式导致卡死解决方案 windows11任务栏显示秒显示秒的注册表设置取消显示秒: OpenWith选择文件打开方式导致卡死 关键在于一个名为openwith的进程出现问题该进程有时会卡死,并且无法关闭,这个bug存在很久了,具体参考:Windows11 - Microsoft Comm…

MySQL 多行函数

文章目录 多行函数1. 求 country 表中&#xff0c;所有国家人口的平均值&#xff0c;其 SQL 语句实现如下&#xff1a;2. 求 country 表中&#xff0c;所有国家人口的总数&#xff0c;其 SQL 语句实现如下&#xff1a;3. 求 country 表中&#xff0c;人口最多和最少国家的人口数…

KD7742耐压接地泄漏绝缘四合一并行测试仪

一、产品简介 KD7742耐压接地泄漏绝缘四合一并行测试仪具有交/直流耐压、绝缘电阻等项目的测试分析功能&#xff0c;能显示电压、电流和电阻的波形图以及趋势图&#xff0c;以便更直观的监测分析绝缘性能和绝缘崩溃时的各项指标&#xff0c;适用于高要求的测试分析场合。 产品具…

Pig项目新加权限类型生成Token并且解决验证问题

前言 这个教程可能不是最好的,也许是最直白的,你只需要找到对应的地方跟着博主一起去修改就能操作成功,今天用添加 mini 的授权模式的例子说一下这个 mini 模式是自己自定义的,你想叫什么都行 最近可烦死了快被折磨死人,在昨天睡了一觉,今天就解决问题了…睡一觉就能解决问题,那…

教你一步步使用实现TensorFlow 进行对象检测

在本文中,我们将学习如何使用 TensorFlow Hub 预训练模型执行对象检测。TensorFlow Hub 是一个库和平台,旨在共享、发现和重用预训练的机器学习模型。TensorFlow Hub 的主要目标是简化重用现有模型的过程,从而促进协作、减少冗余工作并加速机器学习的研发。用户可以搜索社区…

【数据结构与算法分析inC-MarkAllen】2-算法分析

文章目录 第二章——算法分析2.1 算法评价的量化理论2.1.1 函数渐进增长四种渐进增长定义运算法则两个函数相对增长率判断 2.1.2 算法分析的计算机模型2.1.3 要分析的目标最坏情况 2.1.4 一般法则for循环嵌套for循环顺序语句分支语句二分函数调用 2.2 计算方法2.2.1 循环主体中…

Android应用的加固与逆向

文章目录 前言名词释义加固手段逆向dex文件resources.arscReact Native TODO文档链接工具参考加固工具逆向工具 前言 加固与逆向是安卓攻防的两个方面。搞安卓研发时间长了就不可避免走到这一步。既要研究别人的实现&#xff0c;又要保护好自己的东西。个人认为&#xff0c;逆…

糖尿病首创新药的中国梦

《多肽链》原创出品 作者&#xff5c;慕白 在中国上市一款first-in-class&#xff08;FIC&#xff09;全球首创新药&#xff0c;有多难&#xff1f;先来看一组数据对比。 按照美国FDA的药品评价和研究中心&#xff08;CDER&#xff09;报告数据&#xff0c;2022年有37款新药…

chatgpt赋能python:介绍Python中二次函数的基本知识

介绍Python中二次函数的基本知识 在Python中&#xff0c;二次函数是一个重要的概念&#xff0c;它是由一个二次项、一次项和一个常数项构成的一个代数式。二次函数在数学和物理学中都有广泛的应用&#xff0c;了解二次函数的基本知识对于学习和理解这些领域都是非常重要的。在…

uni-app实现 app 小程序 手机端H5扫码功能

首先 扫码这个功能小程序和App都是有现成的方法 但是H5是不行的 我们可以看这样一段代码 <template><view><!-- #ifdef MP-WEIXIN --><button click"scan">扫描</button><view v-if"result">{{result}}</view>…

长尾词挖掘,挖掘百度相关词和下拉词的操作步骤

什么是下拉词 在搜索引擎的搜索框输入一个关键词的时候&#xff0c;搜索框会推荐一些与这个关键词有关联的长尾关键词&#xff0c;如“汉服”。 什么是相关词 在搜索引擎的搜索框输入一个关键词的时候&#xff0c;一般会推荐与这个关键词相关的长尾关键词。如“汉服”。 挖…

【SpringBoot系列】SpringBoot中 @Configuration 和 @Component 的区别及原理分析

示例 //Component Configuration public class AppConfig {Beanpublic Foo foo() {System.out.println("foo() invoked...");Foo foo new Foo();System.out.println("foo() 方法的 foo hashcode: " foo.hashCode());return foo;}Beanpublic Eoo eoo() {…

华为OD机试真题B卷 Java 实现【等差数列】,附详细解题思路

一、题目描述 等差数列 2&#xff0c;5&#xff0c;8&#xff0c;11&#xff0c;14。。。。 从 2 开始的 3 为公差的等差数列。 输出求等差数列前n项和。 数据范围&#xff1a; 1≤n≤1000 。 二、输入描述 输入一个正整数n。 三、输出描述 输出一个相加后的整数。 四…

Dell电脑出现ac power adapter电压异常的解决办法

最近这段时间不知怎么的&#xff0c;dell笔记本电脑一开机就出现下面错误&#xff1a; The AC Power Adapter Wattage Cannot be Determined. 无法确定此交流电源的功率信息。 The Battery Maynot Charge. 电池将可能无法充电。 The System Will Adjust the Performance to Ma…

springboot+java农产品网上购物商城系统005

基于springboot技术的购物商城系统是属于JavaWeb项目&#xff0c;采用的开发框架为springboot框架&#xff0c;也就是Spring mvc、Spring、MyBatis这三个框架&#xff0c;页面设计用的是jsp技术作为动态页面文件设计&#xff0c;jsp文件里可以对实现html等界面布局的代码&#…