mysql索引深度学习

索引是什么?

索引是一种用于加快查询和索引的数据结构,其本质上就是一种排序好的数据结构,就类似书的目录。

索引的底层有多种实现的结构:b树,b+树,Hash,红黑树。InnoDB和MyISAM的索引都是通过b+树实现的。

索引的优缺点

优点

1.使用所以可以大大提高检索的速度(大大减少检索的数据量),这就是创建索引的主要原因。

2.我们可以创建唯一性索引,可以实现保证每行数据的唯一性。

缺点

1.创建和维护索引需要大量的时间,当对表中的数据进行增删改时如果存在索引,则也需要对索引进行修改,这会降低SQL语句的速率。

2.索引也需要物理储存,会消耗一定量的空间内存。

索引底层数据结构的选型

Hash表

使用键值对的方式储存数据,通过hash函数(通过对地址进行取模操作)计算数据储存的索引,通过索引确定位置并储存数据。

hash表存在hash值冲突的问题:两个不相同的数据可能存在相同的hash值。

为了解决这个问题,我们使用拉链法,将hash值相同的数据,在其对应的位置使用链表进行储存。

从而解决hash冲突的问题。

但是innodb没有采用hash表,因为hash表不支持顺序和范围查询,并且每次IO只能返回一个数据 

SELECT * FROM table WHERE id < 500;

如果此时索引使用的hash表的结构,那么它需要将1~499的数据使用hash函数定位出来,效率十分低下。

二叉搜索树

特点:每个节点都符合:左边节点的值都小于当前节点,右边节点的值都大于当前节点。

在理想条件下,节点的左子树的深度和右子树的深度差不会超过一层,此时的时间复杂度为O(logN),而当插入的数据为递增或递减的情况时(斜树),结构就会变成链表的结构,此时的时间复杂度为O(N),效率就大大降低。

但是innodb没有采用二叉搜索树,因为二叉搜索树极度依赖其平衡性,太不稳定了。

AVL(平衡二叉搜索树)

其结构就是一直保持左右子树的高度差为1以内的二叉搜索树。为了解 决二叉搜索树变为链表的情况。

主要通过四种旋转操作控制二叉树的平衡,LL,RR,LR,RL。

在数据的储存上需要频繁依赖旋转操作来保持平衡,需要巨大的计算开销从而影响性能,因为在每个节点上只能储存一个数据,而每次进行IO操作时只能获取一个数据,如果需要查询的数据存在于多个节点上,我们就要多次使用IO操作,非常的耗时(IO操作是非常耗时的),所以innoDB没有使用AVL作为数据结构。 

红黑树

红黑树的特点:

1.节点只能为黑色或红色。

2.叶子节点为黑色。

3.根节点到各个叶子节点的黑色节点的个数是相同的。

4.根节点为黑色。

5.节点为红色,则其父节点为黑色,子节点为黑色。

红黑树的是出现就是为了解决AVL频繁旋转的问题。 

因为红黑树的平衡较弱,其要求就是左右子树的高度在两倍以下,可能会导致树的高度较高,查找次数增多,可能导致一些数据需要多次IO操作才能得到,效率会变的低下,所以innoDB没有使用改数据结构。

B树和B+树(多路平衡查找树)

为了解决红黑树的高度高导致的查询速度慢的问题,我们就使用B树和B+树,它们就是多叉搜索树

B树的特点: 在数据量相同的情况下,平衡二叉查找树的高度要大于B树的高度。

B树的结构

 

B+树的结构

B树和B+树的区别

1.B树的子树数量等于关键字的数量 + 1,2.B树的叶子节点是独立的,而B+树的叶子节点则是使用双向链表进行关联的。

3.B树的所有节点都可以存放key和data,而B+树只有在叶子节点才能存放key和data。
 

InnoDB和MyISAM的索引为什么都是使用B+树实现的呢?

储存相同数据的时候,AVL树的高度比B树要高,所以器其对应的IO的操作次数也更多,为了减少IO的操作次数,我们使用B+树实现索引。

主索引(primary key)

主索引也叫主键。 

在mysql的InnoDB中,如果在表中没有设置主键,InnoDB会自动检查表中是否有唯一索引且没有null值的字段,如果有的话,就会将该字段设置为主索引,如果没有找到自动创建一个6Byte的自增主键。

二级索引

通过二级索引,我们可以确定主键的位置,因为二级索引的叶子节点储存的数据就是主键。

二级索引有: 唯一索引,普通索引,前缀索引,全文索引。

二级索引的种类和作用 

唯一索引: 唯一索引是一种约束,其的作用就是唯一索引的属性列中的数据不能重复,但是其可以为null,用于实现数据的唯一性,在一张表中可以设置到多个唯一索引。

普通索引:用于加快数据的查询速度,在一张表中可以设置多个普通索引。

前缀索引:适用于字符串类型的数据,就是去字符串前缀几个字符作为索引,比普通索引建立的数据更小。

全文索引:全文索引主要是为了检索大文件数据中的关键字的信息。

聚簇索引(聚集索引)

索引的结构和数据一起存放的索引,并不是一种单独的索引类型,InnoDB的主键就是使用聚簇索引。

聚簇索引的优缺点

优点

1.查询速度非常快:因为整个结构就是B+树,所以查询速度非常快,相比于非聚簇索引,聚簇索引少一次IO操作。

2.对排序查找和范围查找优化。

缺点

1.依赖于有序的数据:因为B+树的原因,如果数据无序的情况,在数据插入的时候需要进行排序,效率就很低。

2.更新代价大:因为结构和数据存放在一起,所以在修改的时候更新代价大。

非聚簇索引(非聚索引)

索引的结构和数据不是存放在一起的索引,并不是一种单独的索引类型,二级索引就是非簇索引,MyISAM的主键和非主键都是使用非聚簇索引。

非聚簇的优缺点

优点:更新代价比聚簇索引小。

缺点

1.依赖于有序的数据,其结构是B+树。

2.可能需要二次查询(回表):这是非聚簇索引的最大缺点,当查询到对应的指针或主键后,还需要根据指针或主键再到文件或表中查询。

 

非簇索引一定会进行回表吗?

不一定,当一个索引包含(覆盖)了需要查询字段的所有值的时候,就不需要进行回表操作了。

 SELECT name FROM table WHERE name='guang19';

此时如果字段name正好建立了索引,此时索引包含了所有需要查询的字段,并且不会进行回表操作。

总的来说,如果一个索引包含了所有需要查询的字段的时候(也就是覆盖索引),就不需要回表操作。

 

覆盖索引和联合索引 

 覆盖索引

覆盖索引:查询的所有字段正好是索引的字段,那么直接根据索引查询出数据,无需进行回表操作。

联合索引

联合索引:使用表中多个字段创建索引,该索引就叫作联合索引或组合索引或复合索引。

 

索引下推

索引下推是mysql5.6之后提供的一项索引优化功能,可以在非聚簇索引遍历过程中,对索引包含的字段先进行判断,过滤不符合条件的记录,减少回表的次数。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDA反编译apk修改数据后重新打包

1、需要的工具 apktool、ida、il2cppDumper、ApkSignTools 2、说明 如果是mono打包的&#xff0c;不管是apk还是exe&#xff0c;都可以直接拿到直接从包内拿到 Assembly-Csharp.dll&#xff0c;只要开发者没有对这个文件进行加密&#xff0c;都可以轻松用 ILSpy 或 dnSpy 进行…

汽车标定技术(三)--XCP协议如何支持测量功能

目录 1. 概述 2. 测量方式 -- Poll 3. 测量方式 -- DAQ 3.1 ODT概念模型 3.2 DAQ List概念 3.3 ODT 绝对编号和相对编号 3.4 静态DAQ和动态DAQ模式 &#xff08;1&#xff09;静态DAQ &#xff08;2&#xff09;动态DAQ 4.小结 1. 概述 在该系列的首篇文章汽车标定技…

layui form 中input输入框长度的统一设置

Layui.form中使用class"layui-input-inline"就可轻松将元素都放到一行&#xff0c;但如果元素过多&#xff0c;就会自动换行。那就需要手动设置input框的长度。 像这种情况&#xff1a; 其实只需要添加css样式就可修改了 .layui-form-item .layui-input-inline {wid…

uni-app---- 点击按钮拨打电话功能点击按钮调用高德地图进行导航的功能【安卓app端】

uniapp---- 点击按钮拨打电话功能&&点击按钮调用高德地图进行导航的功能【安卓app端】 先上效果图&#xff1a; 1. 在封装方法的文件夹下新建一个js文件&#xff0c;然后把这些功能进行封装 // 点击按钮拨打电话 export function getActionSheet(phone) {uni.showAct…

05-流媒体-RTMP协议介绍

05-流媒体-RTMP协议介绍 1.RTMP概述 RTMP是一种常见的流媒体协议,是基于TCP/IP协议模型的应用层协议,工作在TCP协议上,端口是1935。通过TCP三次握手保证传输的可靠。 2.握手 2.1 握手过程 RTMP基于传输层TCP连接后,通过RTMP握手协议来完成RTMP连接。客户端和服务端各发…

PTA 函数题(C语言)-- 阶乘计算升级版

题目title&#xff1a; 阶乘计算升级版 题目作者&#xff1a; 陈越 浙江大学 本题要求实现一个打印非负整数阶乘的函数。 函数接口定义&#xff1a; void Print_Factorial ( const int N ); 其中N是用户传入的参数&#xff0c;其值不超过1000。如果N是非负整数&#…

LeetCode:117. 填充每个节点的下一个右侧节点指针 II(C++)

117. 填充每个节点的下一个右侧节点指针 II 题目描述&#xff1a; 给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将…

【Qt-22】Qt乱码问题解决

最近在Qt项目中遇到TCP通信接收数据乱码的问题&#xff0c;很是苦恼&#xff0c;经过多次尝试&#xff0c;终于得以解决。 感谢Qt TcpSocket 传递数据乱码显示_qt中socket接受到的客户端数据显示不出来-CSDN博客 彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)_XX風的博客…

Fourier分析导论——第3章——Fourier级数的收敛性(E.M. Stein R. Shakarchi)

第 3 章 Fourier级数的收敛性(Convergence of Fourier Series) The sine and cosine series, by which one can represent an arbitrary function in a given interval, enjoy among other remarkable properties that of being convergent. This property did not escape…

解决Visual Studio Code 控制台中文乱码问题

C和CPP运行编码指定 "code-runner.executorMap": {"c": "cd $dir && gcc -fexec-charsetGBK $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt","cpp": "cd $dir && g -fexec-charsetGBK $…

虚拟机VirtualBox添加磁盘

一、创建虚拟硬盘 fdisk -l 我们新添加的磁盘/dev/sdb&#xff0c;还没有分区 sdb磁盘分区 fdisk /dev/sdb n 创建一个新分区 选择p添加主分区 我们把所有10GB空间都格式化为一个分区了 。 w 键入w&#xff0c;保存设置并退出&#x…

2023.10.31 关于 Spring 的基本概念

目录 Spring 容器 对象生命周期 IoC Spring IoC DI Spring Spring 的全称为 Spring Framework&#xff0c;是一个开源的 Java 应用程序框架它提供了一种综合的编程和配置模型&#xff0c;用于构建现代化企业级的应用程序 一句话概括 Spring 是包含了众多工具方法的 IoC …