【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多?

news2024/11/15 8:49:14

【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多?

文章目录

  • 【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多?
    • 磁盘IO和预读:
    • 索引是什么?
    • BTree索引
    • B+Tree索引

让我们先来了解一下计算机的数据加载。

磁盘IO和预读:

image-20221226223202098

先说一下磁盘IO,磁盘读取数据靠的是机械运动,每一次读取数据需要寻道、寻点、拷贝到内存三步操作。

寻道时间是磁臂移动到指定磁道所需要的时间,一般在5ms以下;

寻点是从磁道中找到数据存在的那个点,平均时间是半圈时间,如果是一个7200转/min的磁盘,寻点时间平均是600000/7200/2=4.17ms;

拷贝到内存的时间很快,和前面两个时间比起来可以忽略不计,所以一次IO的时间平均是在9ms左右。听起来很快,但数据库百万级别的数据过一遍就达到了9000s,显然就是灾难级别的了。

image-20221226223223824

image-20221226223241589

考虑到磁盘IO是非常高昂的操作,计算机操作系统做了预读的优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。

每一次IO读取的数据我们称之为一页(page),具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO。

(突然想到个我刚毕业被问过的问题,在64位的操作系统中,Java中的int类型占几个字节?最大是多少?为什么?)

那我们想要优化数据库查询,就要尽量减少磁盘的IO操作,所以就出现了索引。

索引是什么?

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。

MySQL中常用的索引在物理上分两类,B-树索引和哈希索引。

本次主要讲BTree索引。

BTree索引

BTree又叫多路平衡查找树,一颗m叉的BTree特性如下:

  • 树中每个节点最多包含m个孩子。
  • 除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子(ceil()为向上取整)。
  • 若根节点不是叶子节点,则至少有两个孩子。
  • 所有的叶子节点都在同一层。
  • 每个非叶子节点由n个key与n+1个指针组成,其中[ceil(m/2)-1] <= n <= m-1 。

image-20221226223315879

这是一个3叉(只是举例,真实会有很多叉)的BTree结构图,每一个方框块我们称之为一个磁盘块或者叫做一个block块,这是操作系统一次IO往内存中读的内容,一个块对应四个扇区,紫色代表的是磁盘块中的数据key,黄色代表的是数据data,蓝色代表的是指针p,指向下一个磁盘块的位置。

来模拟下查找key为29的data的过程:

1、根据根结点指针读取文件目录的根磁盘块1。【磁盘IO操作1次

2、磁盘块1存储17,35和三个指针数据。我们发现17<29<35,因此我们找到指针p2。

3、根据p2指针,我们定位并读取磁盘块3。【磁盘IO操作2次

4、磁盘块3存储26,30和三个指针数据。我们发现26<29<30,因此我们找到指针p2。

5、根据p2指针,我们定位并读取磁盘块8。【磁盘IO操作3次

6、磁盘块8中存储28,29。我们找到29,获取29所对应的数据data。

由此可见,BTree索引使每次磁盘I/O取到内存的数据都发挥了作用,从而提高了查询效率。

但是有没有什么可优化的地方呢?

我们从图上可以看到,每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。

B+Tree索引

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。

image-20221226223325985

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

非叶子节点只存储键值信息, 数据记录都存放在叶子节点中, 将上一节中的B-Tree优化,由于B+Tree的非叶子节点只存储键值信息,所以B+Tree的高度可以被压缩到特别的低。

具体的数据如下:

InnoDB存储引擎中页的大小为16KB,一般表的主键类型为INT(占用4个字节)或BIGINT(占用8个字节),指针类型也一般为4或8个字节,也就是说一个页(B+Tree中的一个节点)中大概存储16KB/(8B+8B)=1K个键值(因为是估值,为方便计算,这里的K取值为〖10〗^3)。

也就是说一个深度为3的B+Tree索引可以维护10^3 * 10^3 * 10^3 = 10亿 条记录。(这种计算方式存在误差,而且没有计算叶子节点,如果计算叶子节点其实是深度为4了)

我们只需要进行三次的IO操作就可以从10亿条数据中找到我们想要的数据,比起最开始的百万数据9000秒不知道好了多少个华莱士了。

而且在B+Tree上通常有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。所以我们除了可以对B+Tree进行主键的范围查找和分页查找,还可以从根节点开始,进行随机查找。

数据库中的B+Tree索引可以分为聚集索引(clustered index)和辅助索引(secondary index)。

上面的B+Tree示例图在数据库中的实现即为聚集索引,聚集索引的B+Tree中的叶子节点存放的是整张表的行记录数据,辅助索引与聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据,而是存储相应行数据的聚集索引键,即主键。

当通过辅助索引来查询数据时,InnoDB存储引擎会遍历辅助索引找到主键,然后再通过主键在聚集索引中找到完整的行记录数据。

不过,虽然索引可以加快查询速度,提高 MySQL 的处理性能,但是过多地使用索引也会造成以下弊端

  • 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
  • 除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大。
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

注意:索引可以在一些情况下加速查询,但是在某些情况下,会降低效率。

索引只是提高效率的一个因素,因此在建立索引的时候应该遵循以下原则:

  • 在经常需要搜索的列上建立索引,可以加快搜索的速度。
  • 在作为主键的列上创建索引,强制该列的唯一性,并组织表中数据的排列结构。
  • 在经常使用表连接的列上创建索引,这些列主要是一些外键,可以加快表连接的速度。
  • 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,所以其指定的范围是连续的。
  • 在经常需要排序的列上创建索引,因为索引已经排序,所以查询时可以利用索引的排序,加快排序查询。
  • 在经常使用 WHERE 子句的列上创建索引,加快条件的判断速度。

建索引,因为索引已经排序,所以其指定的范围是连续的。

  • 在经常需要排序的列上创建索引,因为索引已经排序,所以查询时可以利用索引的排序,加快排序查询。
  • 在经常使用 WHERE 子句的列上创建索引,加快条件的判断速度。

现在大家知道索引为啥能这么快了吧,其实就是一句话,通过索引的结构最大化的减少数据库的IO次数,毕竟,一次IO的时间真的是太久了。。。

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

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

相关文章

中国为印尼建设的高铁顺利推进,印度网友与日本网友就高铁互怼

日前中国为印尼建设的雅万高铁已开始进行试运行测试&#xff0c;预计将在明年6月正式运行&#xff0c;与雅万高铁差不多时间开始的日本为印度孟买建设的高铁项目才建设了15公里&#xff0c;为此印度网友和日本网友对中日高铁技术的差距展开了争论。2011年日本相关机构开始对印尼…

羊的第四天,开始这篇年终总结

比较尴尬&#xff0c;从今年“羊”到明年&#xff0c;所以这篇文章也是每天抽出一点时间写写&#xff0c;可能会比较乱&#xff0c;先大致分下核心内容吧&#xff1a;今年总结新年展望今年总结先是完成了《数字硬件建模系列的Verilog篇》&#xff0c;效果不好不坏&#xff0c;主…

算法设计与分析复习03:动态规划算法

算法设计与分析复习03&#xff1a;动态规划算法 文章目录算法设计与分析复习03&#xff1a;动态规划算法复习重点动态规划算法斐波那契数列及其应用矩阵链乘法凸多边形剖分矩阵链乘法凸多边形剖分最长公共子序列最大子段和&#xff08;字数组&#xff09;0-1背包编辑距离钢条切…

pycharm-qt5-designer1

pycharm-qt5-designer1一: designer界面介绍1. 新建模板二: 控件箱简介1. Layouts 布局2. Spacers 间隔(透明)3. Button4. Item views5. Item Widgets 条目控件6. Containers 容器7. input Widgets 输入控件8. Display Widgets 显示控件三: 控件属性简介1. sizePolicy: 控件大小…

gitlab-ci.yml关键字(四)allow_failure 、artifacts 、cache

allow_failure 我们知道&#xff0c;流水线作业在运行时如果失败了&#xff0c;就会停止运行&#xff0c;但allow_failure可以让我们自由的控制当前作业失败时&#xff0c;是否还需要继续运行。 要让管道继续运行后续作业&#xff0c;请使用allow_failure: true要停止管道运行…

OASIS协议标准文档的解读_第一部分

译者注&#xff1a; 利用2022年圣诞假期&#xff0c;终于解读完OASIS标准协议的文档。本翻译文档基于SEMI 草案标准 3626 (2003/04/23). 因为SEMI的原版标准草案涉及到版权的一些问题&#xff0c;并不是公开的。因此我并不是原文原样翻译&#xff0c;会加入很多我自己的理解和…

cnpm : 无法将“cnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

从报错来看明显是没有装 cnpm 检查本地是否安装了cnpm包管理工具 命令&#xff1a;npm list --depth0 -global 查看一下电脑是否安装了cnpm 如果已经安装了&#xff0c;那么会有如下图所示的内容&#xff1a; 从以上来看确实是没有装 则需要安装镜像&#xff0c;执行命令为…

Vue3详细讲解

Vue 3 介绍 文章目录Vue 3 介绍为什么要学习 vue 3Vue3 动机 和 新特性Vite 的使用vite介绍为什么选 Vite &#xff1f;Vite 的基本使用Vue3.0项目介绍vscode插件说明组合式APIcomposition API vs options API体验 composition APIsetup 函数reactive 函数ref 函数script setup…

【云原生 | Kubernetes 实战】19、K8s Ingress-Controller 高可用方案

目录 一、Ingress 和 Ingress Controller 概述 1.1 回顾下 service 四层代理 1.2 Ingress 介绍 1.3 Ingress Controller 介绍 1.4 Ingress 和 Ingress Controller 总结 1.5 使用 Ingress Controller 代理 k8s 内部 pod 的流程 二、创建两个 ingress-controller 高可用…

凌云驭势 亚马逊云科技开启re:Invent中国行

‍‍数据智能产业创新服务媒体——聚焦数智 改变商业近日&#xff0c;亚马逊云科技召开了2022 re:Invent全球大会。作为云计算的开创者&#xff0c;每年亚马逊云科技举办的re:Invent全球大会都会成为产业的风向标&#xff0c;备受业内人士关注。2022年&#xff0c;面对全球数字…

【STL学习之路】vector的模拟实现

文章目录一、接口总览二、vector成员变量三、默认成员函数构造函数① -- 默认无参构造构造函数② -- 迭代器区间构造构造函数③ -- n个val构造拷贝构造函数赋值运算符重载析构函数四、迭代器六、容量以及元素访问的相关接口emptysize和capacityreserveresize七、增删查改等接口…

async await 的基础使用和实现原理

async await 使用基础原理 async/await用法 其实你要实现一个东西之前&#xff0c;最好是先搞清楚这两样东西 这个东西有什么用&#xff1f; 这个东西是怎么用的&#xff1f; 有什么用&#xff1f; async/await的用处就是&#xff1a;用同步方式&#xff0c;执行异步操作&…

商会机构源码模板系统包含了信息管理、新闻管理、广告管理、系统管理等功能 v3.9

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 XYCMS商会机构源码模板系统是以aspaccess进行开发的商会网站源码&#xff0c;包含了信息管理、新闻管理、广告管理、系统管理等功能。 XYCMS商会机构源码模板系统功能简述&#xff1a; 商…

大数据面试题Spark篇(1)

1.spark数据倾斜 数据倾斜俩大直接致命后果&#xff1a;Out Of Memory&#xff0c;运行速度慢。这主要是发生在Shuffle阶段。同样Key的数据条数太多了。导致了某个key所在的Task数据量太大了&#xff0c;远远超过其他Task所处理的数据量。 数据倾斜一般会发生在shuffle过程中…

使用Eclipse开发第一个Java程序

虽然在《使用记事本编写运行Java程序》一节中已经开发过一个 Java 程序&#xff0c;但是那毕竟是通过记事本创建的。在上一节《Java Eclipse下载安装教程》中&#xff0c;我们已经安装了 Eclipse 工具&#xff0c;因此本节将介绍如何通过 Eclipse 开发 Java 程序。 在 Eclipse …

SD存储卡介绍

SD存储卡简介 SD存储卡是一种基于半导体快闪记忆器的新一代记忆设备&#xff0c;由于它体积小、数据传输速度快、可热插拔等优良的特性&#xff0c;被广泛地于便携式装置上使用&#xff0c;例如数码相机、平板电脑、多媒体播放器等。 SD存储卡实物图 SD存储卡特点 1、高存储容…

痞子衡嵌入式:Farewell, 我的写博故事2022

-- 题图&#xff1a;苏州荷塘月色 2022 年的最后一天&#xff0c;写个年终总结。困扰大家三年之久的新冠疫情终于在 12 月全面放开了&#xff0c;痞子衡暂时还没有阳&#xff0c;计划坚持到总决赛。对于 2023 年&#xff0c;痞子衡还是充满期待的&#xff0c;慢慢要恢复到 2019…

Codewars 你虐我千百遍,我待你如初恋

本人最近接触了Codewars啥的&#xff0c;没什么见识哈哈哈哈&#xff0c;刚开始看不懂啥的&#xff0c;到后面看多了其实也还好。我是小白轻点喷&#xff01;&#xff01;&#xff01;接下来就让我展示第一次写文章的历程吧&#xff0c;showTime&#xff1a; 第一位嘉宾A出场 …

2022年终总结:生活就像一道过山车

又到了年末&#xff0c;今年的年终总结我考虑了很久&#xff0c;到底要不要写&#xff1f;可以写些什么&#xff1f; 今年过得十分匆忙&#xff0c;我一直在赶路&#xff0c;但事实上今年内做完的&#xff0c;能说出口的事可以说没有。 回顾下去年对今年的期望&#xff1a; 有…

魔幻2022,2023涅槃重生!

前言&#xff1a; 大家好&#xff0c;按照惯例&#xff0c;每年的年尾&#xff0c;这个时候我都会进行复盘&#xff0c;这是自己第4个年头进行年度复盘&#xff1a;总结2019&#xff0c;展望2020&#xff01;不管过去如何&#xff0c;未来我们都要奋力前行&#xff01;复盘2021…