深入浅出MYSQL索引实现机制

MySQL索引机制解析:B+树、索引类型与优化策略 本文深入解析MySQL索引机制,重点介绍B+树、聚簇/非聚簇索引、索引优化技术。B+树因其更少的磁盘I/O、高效范围查询和稳定性能成为MySQL首选索引结构。聚簇索引存储完整数据行,而非聚簇索引需回表查询。索引下推(ICP)减少回表次数,覆盖索引避免回表提升查询效率。自适应哈希索引(AHI)自动为热点数据创建哈希索引,将查找复杂度降至O(1)。理解这些机制对数据库性能优化和SQL查询调优至关重要。 阅读详情

一、什么是索引

       提到数据库索引,我想你并不陌生,在日常工作中会经常接触到。比如 我们的某一个SQL查询语句响应很慢,你可能第一反应是 给这个SQL 加个索引吧,那么到底什么是索引昵,今天我们就来聊一下这个话题(本文以MYSQL 5.6 为例)。

       索引是为了加速对表中数据的检索速度而创建的一种数据结构,索引是在存储引擎层实现的,在MYSQL里面,不同的存储引擎实现索引的方式不太一样,本文以主流的INNODB存储引擎为例进行说明。比如我们有一个user表,主键id对应有一个索引,形如 

     上图是一个主键索引和具体数据之间的映射关系。

二、索引有什么优势、劣势

        首先,如果没有索引,MYSQL是如何来检索数据的昵,下面我们举一个简单的例子,比如我们要对上面的user表进行精确匹配,假设查找name="张三"的记录,

select * from user where name = "张三"

       目前我们的表只有2条记录,假设这2条记录都存在某一页上,因为我们并没有对name列建立索引,MYSQL就只有挨个扫描进行数据比对,极端情况下,假设我们有成千上万的记录,这些数据存储在很多页上,如果我们要检索某行数据,我们首先需要定位到数据存储在哪一页,然后从所在的页内中查找相应的记录才进行扫描,而如果我们没有建立索引,也只能笨办法一个一个扫描,因为要遍历所有的数据页,所以这种方式显然是非常耗时的。那么,有没有一种方式能够加快数据的检索速度昵,索引闪亮登场了。

       那么,使用索引有什么优势昵?首先索引可以减少存储引擎需要扫描的数据量,上面的例子已经明显感觉到,全表扫描需要扫描的数据量有多恐怖,其次,可以在一定情况下避免对数据进行排序,当我们使用order by 进行排序的时候,mysql首先会判断内存能不能装得下你要排序返回得数据,如果可以,就直接在内存里面计算不需要借助于临时表,并且,恰好如果你要排序的字段本身就是索引字段,而索引在INNODB的叶子节点存储的数据又是有序的,那么连在内存里面排序这一步都可以省掉,直接从叶子节点扫描满足的数据即可。

      事物总有二面性,索引可以帮助我们更快的检索我们想要的数据,但是使用索引也是有代价的。当我们的表数据非常大的时候,一棵B+Tree所需要的空间也是非常大的,而且每一个索引就是一棵B+Tree,显然,这些数据放在内存是不现实的,索引真正落地的地方还是磁盘,这是索引空间上的代价。而当我们对某一列建立了索引之后,当我们对这一列进行修改的时候,MSQL 需要维护索引, 比如对记录的修改,可能会造成页节点的分裂,申请新的数据页等,这是索引时间上的代价。所以,索引并不是越多越好,最好结合业务合理设置索引。

三、为什么是B+Tree

      索引的出现是为了提高查询效率,但是实现索引的底层数据结构却有很多种,比如哈希表,有序数组,树等,那么INNODB为什么要使用B+Tree来实现昵?

  3.1 哈希表

       假如我们使用哈希表来实现,哈希表是一种K-V存储数据的结构,我们输入待匹配的Key,就能找到对应的Value,当多个Key经过Hash之后出现冲突的时候,很简单,后面我跟一个链表,当我们检索一个数据的时候,首先根据检索的Key 计算其HashCode然后找到对应数组的下标,然后根据Equals进行比较,找到我们需要的数据。看起来哈希表查找数据的效率很高,但是这仅仅出现在等值查询的情况,假设我们查找user表里面,age 在【10,2000】的结果,哈希表做起来就吃力了,只能进行全表扫描。而显然,这种范围查询在我们的业务中是非常常见的。所以,哈希数据结构不合适做索引。

  3.2 有序数组

       假如我们用有序数组来实现,比如一个有序数组 new int [] { 1,2,3,4,8} 当我们检索 age 大于3 且 小于 8的数据,首先可以根据二分法找到 3,然后向右遍历,直到数据大于8即可,看起来范围查找的效率可以达到O(LogN),但是假设我们更新一条数据昵,比如我插入一个6,那么6之后的数据就必须往后移动一位,如果数据量非常大的化,这个代价太大了,所以,有序数组不太适合我们这种数据动态变化的情况。

 3.3 二叉查找树

      二叉查找树,典型的特征就是 从根节点开始,它的左子树的值比根节点的键值小,右子树的值比根节点的键值大,比如下面这就是一棵二叉查找树(网址 https://www.cs.usfca.edu/~galles/visualization/BST.html)

 

     上面是一种比较极端的情况,树型结构成线性了, 假设我们需要查找id=10的记录,就需要5次IO, 这还是数据量很少的情况,而磁盘IO往往是最耗时的地方,所有,二叉查找树不适合用来做索引。

3.4 AVL 树(平衡二叉树)

       平衡二叉树(AVL树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为1,比如下面这棵树

      如果在AVL树中进行插入或删除节点,可能导致AVL树失去平衡,AVL树失去平衡之后,可以通过旋转使其恢复平衡,这里不介绍其是如何保持平衡的,具体可以打开上面的网址进行演示。当我们要查找id=9的数据时,首先将id=7加载到内存中,发现 9 > 7 ,然后查找其右子树,发现 9 < 37,接着查找 37 的左子树,直到找到匹配的数据。对于AVL树来说,可能会存在树的高度太深,极端情况下,如果我们要查找的数据在树的最底层,那么IO次数将明显增加,这也不利用数据的检索效率的提升。

3.5 多路平衡查找B-Tree 树/B+Tree

      为了让一个查询尽量少地读磁盘,就必须让查询过程访问尽量少的数据块,那么二叉树就不合适了,可以考虑使用多叉树。

      对于B-Tree(https://www.cs.usfca.edu/~galles/visualization/BTree.html)来说,它的特点其实没有必要去死记硬背,主要核心是 B-Tree 里面每个节点中不仅包含数据的key值,还有data值。下面就是一棵B-Tree

       上图中,树的每一个节点都是具体的key-value值,但是,每一个 page的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,最坏的情况是一个 page 保存一条数据,这个时候 B 树退化成二叉树;另外 B 树无法修改字段最大长度,除非调整 page 大小,重建整个数据库,为了解决这些问题,B-Tree树的增强版B+Tree出现了。

       在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大增加每个节点存储的key值数量,降低B+Tree的高度。

    B+Tree相对于B-Tree有几点不同:

  1. B+节点关键字搜索采用闭合区间
  2. B+非叶节点不保存数据相关信息,只保存关键字和子节点的引用
  3. B+关键字对应的数据保存在叶子节点中
  4. B+叶子节点是顺序排列的,并且相邻节点具有顺序引用的关系

四、MYSQL中B+Tree的体现形式

      接下来我们以主流的存储引擎Innodb和Myisam为例,分别来看索引是如何体现得。

      首先来看Myisam,在Myisam里面,叶子节点存储得是数据记录的指针,并没有存具体的数据,也就是说他的索引和数据是分开存储的,而对应InnoDB来说,我们假设id是某张表的主键,那么以id为索引的B+Tree长下面这样

  

     可以看到,叶子节点存了具体的数据,而假设我们以name列建立了索引,那么这棵B+Tree长下面这样

  

     也就是说,非主键索引的叶子节点存储了对主键索引的指针。也即当我们根据name进行查找的时候,最后都需要进行回表(回主键索引)查一次来获取具体的数据。

五、常用索引介绍

  5.1 聚簇索引

         “聚簇”就是索引和记录紧密在一起,分开就不是聚簇索引了,所以一张表只能有唯一的聚簇索引,比如一般我们一张表只有一个主键,假设是id,那么以id为索引,可以理解为就算一个聚簇索引。

  5.2 唯一索引

        唯一索引是指某几个字段合并成得索引,那么这几个字段在某张表里面如果同时出现,必须仅仅出现一次。

   5.3 覆盖索引

        覆盖所有是指一个索引包含所有需要查询的字段的值,就是说叶子节点的数据已经包含了我需要查询的所有数据,就没有必要再回表(回到主键索引树搜索的过程)查询一次,比如select name,age from T where name="zs";如果我建了一个(name,age)得联合索引,那么该语句不仅可以走索引,而且不用回表查,因为索引树里面已经包含了name和age,而我查询语句需要得数据就是name和age,这种就是覆盖索引。

   5.4 前缀索引

        就是说可以给某个字段得前N个字符设置一个索引,比如前5个字符的区分度就已经很高了,可以不必要对一个很长的字符串建一个索引。这也是为字符串建立索引时一个优化的点。

   5.5 联合索引

       联合索引是指同时有几个字段来组成一个索引,比如 为(name,age)创建一个索引,那么这个索引就是联合索引,在建立联合索引的时候,我们尽量遵循下面的规则。

       5.5.1 将经常用的列放在左边

       5.5.2 将选择性高的列放在左边

       5.5.3 将占用空间少的列放在左边

       一般情况下尽量遵循以上原则

    5.6 最左匹配

        比如我建立了一个(name,age)的联合索引,如果sql语句是 select * from T where name="zs";那么是可以用到这个索引的,但是如果sql语句是 select * from T where age=1 是用不到这个索引的。

六 、索引总结

     我们平时在使用索引的时候,尽量遵循下面的原则

   1、不要对选择性很低的列建立索引,得不偿失。

   2、频繁作为查询条件的列建议建立索引。

   3、查询中与其他表相关的字段,即外键关系考虑建立索引。

   4、查询中统计或者分组的字段建议建立索引。

   5、如果一个表数据量很少,比如就几百条,可以不用建立索引,因为mysql在执行sql请求的时候,会计算成本,如果表的数据量很少,可能直接就走全表扫描了。

【MYSQL】索引机制概述 对于MySQL索引就是用来帮助表快速检索目标数据的。此时先来简单回顾一下MySQL中索引是如何使用的呢?首先需要创建索引,MySQL可以通过三种方式创建一个索引。 阅读详情

相关推荐

Python小白也能玩转迅投QMT量化交易?手把手教你从安装到第一个策略

本文为零基础Python用户提供了上手迅投QMT量化交易平台的完整指南。从Python 3.6环境配置、QMT客户端获取安装,到核心概念讲解,并手把手教你编写并回测一个经典的双均线交易策略,帮助初学者快速迈出量化交易的第一步。

weixin_29103191的博客 763

MySQL—索引机制详解

MySQL 官方定义索引为一种帮助数据库高效获取数据的结构,其本质是排好序的快速查找数据结构。数据库除了存储表中的数据,还维护一些额外的满足特定查找算法的数据结构,这些数据结构以某种方式指向实际的数据,从而加快查询的速度。这种额外维护的数据结构就是索引。由于索引是在存储引擎层实现的,不同的存储引擎对索引的实现方式可能不尽相同,因此没有统一的索引标准。索引的使用数据库中的索引可以类比为书籍的目录,它指向实际的数据,帮助快速定位。下图展示了索引的工作原理:在图中,左边是一张数据表,包含两列和七条记录。

m0_74293254的博客 1332

STM32F4三重ADC+DMA双缓冲实战:用CubeMX搞定同步采样,告别数据覆盖烦恼

本文详细介绍了STM32F4三重ADC与DMA双缓冲技术的实战应用,通过CubeMX配置实现同步采样,解决数据覆盖问题。内容涵盖硬件架构解析、CubeMX工程配置、双缓冲实现技巧及调试优化方法,适用于电机控制、电力监测等需要高精度多通道信号采集的场景。

weixin_30627341的博客 357

【MySQL】MySQL存储引擎以及索引

一、存储引擎MySQL中的数据用各种不同的技术存储在文件中,这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。这些不同的技术以及配套的相关功能在 MySQL中被称作存储引擎(也称作表类型)。我的理解是,数据存储使用不同的数据结构,使得它们各自支持不同的技术和功能,因此划分成不同的存储引擎。而存储引擎是对应表的,所以也被称为表类型。用以下指令可以查看My

偷得浮生半日闲 5779

倍福ADS通讯协议深度解析——从握手到数据包的完整旅程

本文以工程师视角,通过Wireshark抓包实战,深度解析了倍福ADS通讯协议的完整工作流程。从TCP三次握手建立连接,到拆解AMS/TCP信封、AMS Header地址与命令解析,再到ADS Data读写请求的载荷构成,完整呈现了一次数据通讯的“旅程”。文章重点剖析了协议包格式,并结合实际案例,提供了基于协议分析的故障排查思路,帮助开发者深入理解并精准调试工业自动化系统通讯。

weixin_29231725的博客 151

【STM32-DSP库的使用】基于Keil5 + STM32CubeMX + CMSIS-DSP 手动添加、库添加方式

CMSIS-DSP库在工程中应用遇到的所有问题进行归纳终结

洋洋的博客 1万+

数据库—索引底层实现详解

若查询所需字段全部包含在索引中(覆盖索引),数据库可直接从索引页获取数据,无需回表查询主数据文件,减少I/O开销。的映射关系,使数据库无需全表扫描即可快速定位目标数据,极大降低磁盘I/O次数。索引按特定顺序(如B+树的排序)组织键值,使范围查询(如。)无需额外排序步骤,直接遍历索引结构即可高效完成。类似书籍目录,索引通过存储。

z17826856787的博客 1946

Simscape Multiboby学习笔记1——跟着官网学Multibody

文章目录一. 引言二. Simscape Multibody自学之路三. 本教程的目录 一. 引言 最近在倒腾Matlab的动力学仿真,起因是看到有人推荐Matlab的multbody模块,一经了解之下简直惊为天人。作为一名Matlab的小粉,看到这么好用的模块简直不要太开心,之前用simulink搭飞行器的仿真模型,虽然能够仿真看到六自由度位移,毕竟不能可视化,还是很不够直观,而且simulink仿真(以及更费力的脚本文件仿真)需要精确建模,模型不精确计算也是天差地别。而Multibody在具备其他动力学

qq_30267617的博客 8241

索引的原理

官方上面说索引是帮助MySQL高效获取数据的数据结构,通俗点的说,数据库索引好比是一本书的目录,可以直接根据页码找到对应的内容,目的就是为了加快数据库的查询速度。索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。索引数据结构。

leshen_88的博客 963

杰理AC695N芯片跑iic接口的oled驱动分享

本文介绍了一个基于IIC接口的0.96寸OLED显示屏驱动程序,适用于SSD1306控制器。驱动采用软件模拟IIC方式,支持字符、数字、字符串、汉字和图片显示,测试平台为杰理AC695N系列芯片。硬件参数包括128×64分辨率,IIC接口(地址0x78),使用IO_PORTA_02(SDA)和IO_PORTA_03(SCL)引脚。驱动包含OLED主文件(oled.c/h)、软件IIC实现(soft_iic.c/h)和字体/图片数据文件(oledfont.h/bmp.h),可通过修改soft_iic.h中的引

qq_42014563的博客 882

cesium vue2/vue3教程目录导航

以下是本专栏目录导航,送完整项目源码(拒绝单页源码),可以直接运行,全部配置免费视频教程(B站)。

qq_29384639的博客 4317

数据库索引机制

索引的本质   MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。   我们知道,数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化。最基本的查询算法当然是顺序查找(linear search),这种复杂度为O(n)的算法在数据量很大时显然是糟糕的,好在计算机科学的发展提供了很多更优秀的查找算法,例如二分查找(binary search)、二叉树查

lingdian23的专栏 869

9、眼底图像智能分析:糖尿病视网膜病变的自动化识别与分级系统

本博客介绍了一种基于深度学习的糖尿病视网膜病变(DR)自动化识别与分级系统。该系统通过视网膜图像的预处理、数据增强、集成模型的构建与优化,实现了对DR的高效识别与分级。识别系统采用二分类任务,准确率达到97.67%,而分级系统通过四分类策略取得了95.2%的准确率。系统在基层社区和医院中具有广泛的应用前景,为DR的早期筛查和精准诊断提供了有效工具。

pea55的博客 144

mysql 什么是索引_Mysql高手系列 - 第21篇:什么是索引?

Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能。这是Mysql系列第21篇。本文开始连续3篇详解mysql索引:第1篇来说说什么是索引?第2篇详解Mysql中索引的原理第3篇结合索引详解关键字explain本文为索引第一篇:我们来了解一下什么是索引?路人在搞计算机之前,是负责小区建设规划的,上级领导安排路人负责一个万人小区建设规划,并提了一个要求:可以快速通过户主...

weixin_39604897的博客 110

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【MySQL笔记】正确的理解MySQL的索引机制以及内部实现(一)

让我们一起学习大而复杂的数据库索引机制!尽量的做到全面且正确

长路漫漫的歇脚处 5565

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

MySQL索引深入浅出

与其他数据库例如 Oracle 和 SQL Server 等数据库中只有一种存储引擎不同的是,MySQL 有一个被称为“Pluggable Storage Engine Architecture”(可替换存储引擎架构)的特性,也就意味着 MySQL 数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎。

追风少年仍在追风~ 764

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【MySQL笔记】正确的理解MySQL的索引机制以及内部实现(二)

正确的理解MySQL的索引机制以及内部实现, 第二部分更倾向于讲解MySQL B+树索引的实现原理

长路漫漫的歇脚处 3966

MySQL中的事务、索引、锁机制

Mysql学习整理

qq_39026874的博客 2302

MySQL存储引擎及索引机制

插件式存储引擎是MySQL数据库最重要的特性之一,用户可以根据应用的需要选择如何存储和索引数据、是否使用事务等。InnoDBMyISAMMemory等等,在mysql 的命令行窗口中,我们可以通过命令查看。

icc_hhy的博客 1430

Java-96 深入浅出 MySQL 索引与排序机制详解与优化实践 Filesort

利用索引排序(Index Order By)和文件排序(Filesort)。索引排序依赖索引的有序特性,性能优越,适用于 ORDER BY 列顺序与索引定义完全一致、方向相同且遵循最左前缀原则的场景;Filesort 则在无法直接利用索引时执行额外的排序操作,包括双路排序(先取排序键再回表)和单路排序(一次性取全列排序)。双路排序内存占用低,但需二次磁盘读取;单路排序减少磁盘访问,但可能因超出 sort_buffer_size 而产生临时文件。优化策略包括:设计与查询匹配的索引、使用覆盖索引。

谢谢你的喜欢 我们一起无限进步 1276

一文彻底理解 MySQL 的索引机制

MySQL索引是数据库性能优化的关键,其核心在于减少磁盘I/O操作和避免全表扫描。索引采用B+Tree结构,相比二叉树、平衡树和B树,B+Tree能有效控制树的高度,减少查询时的磁盘访问次数,并且支持高效的范围查询。创建高性能索引需遵循最左前缀匹配原则,优先选择区分度高的列作为索引,并针对大字段使用前缀索引优化。理解索引的工作原理和数据结构选择,能够显著提升数据库查询效率,减少系统资源消耗。

数据知道的博客 1万+

【MySQL】数据库的索引机制

MySQL数据库索引的定义、操作、背后的数据结构

flmz_Kk的博客 2591

程序员必须了解的知识点——你搞懂mysql索引机制了吗?

索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL 高效 获取数据的数据结构。 在使用数据库中,通常数据库查询是数据库的最主要功能之一。但每种查找算法都只能应用于特定的数据结构之上。 例如二分查找要求被检索数据有序 而二叉树查找只能应用于二叉查找树上,但是数据本身的组织结构不可能完全满足各种数据结构(例如,理论上不可能同时将两列都按顺序进行组织),所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现

牧小农 5645

一文了解MySQL索引机制

接触MySQL数据库的小伙伴一定避不开索引,索引的出现是,就像书的目录一样。某一个SQL查询比较慢,你第一时间想到的就是“给某个字段加个索引吧”,那么一起静下心来,耐心看完这篇文章吧,干货不啰嗦,相信你一定会有所收获。

京东科技开发者 1034

mysql索引机制深度剖析

mysql索引机制深度剖析

2302_80190394的博客 910

MySQL索引机制精讲

接触MySQL数据库的小伙伴一定避不开索引,索引的出现是为了提高数据查询的效率,就像书的目录一样。某一个SQL查询比较慢,你第一时间想到的就是“给某个字段加个索引吧”,那么索引是什么?是如何工作的呢?一起静下心来,耐心看完这篇文章吧,干货不啰嗦,相信你一定会有所收获。

无休居士的博客 1736
上一篇: 浅析MyBatis的工作原理
下一篇: 一次生产问题的排查---解决springboot集成dubbo并使用外部容器部署在应用重启出现dataSource has already close 异常
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值