MySQL索引能让查询效率提高这么多原因是?

MySQL索引能让查询效率提高这么多原因是?

背景

我相信大家在数据库优化的时候都会说到索引,我也不例外,大家也基本上能对数据结构的优化回答个一二三,以及页缓存之类的都能扯上几句,但是有一次阿里p9的一个面试问我:你能从计算机层面开始说一下一个索引数据加载的流程么?(就是想让我聊io)

我当场就去世了….因为计算机网络和操作系统的基础知识真的是我的盲区,不过后面我恶补了,废话不多说,我们就从计算机加载数据聊起,讲一下换个角度聊索引。

正文

MySQL的索引本质上是一种数据结构

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

磁盘IO和预读:

MySQL索引能让查询效率提高这么多原因是?

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

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

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

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

MySQL索引能让查询效率提高这么多原因是?
MySQL索引能让查询效率提高这么多原因是?

考虑到磁盘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 。

MySQL索引能让查询效率提高这么多原因是?

这是一个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取到内存的数据都发挥了作用,从而提高了查询效率

蓝心千询 蓝心千询

蓝心千询是vivo推出的一个多功能AI智能助手

蓝心千询 34 查看详情 蓝心千询

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

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

B+Tree索引

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

MySQL索引能让查询效率提高这么多原因是?

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索引能让查询效率提高这么多原因是?

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

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

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

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

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

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

总结

就面试而言很多知识其实我们可以很容易就掌握了,但是要以学习为目的,你会发现很多东西我们得深入到计算机基础上才能发现其中奥秘,很多人问我怎么记住这么多东西,其实学习本身就是一个很无奈的东西,既然我们不能不学那为啥不好好学?去学会享受呢?最近我也在恶补基础,后面我会开始更新计算机基础和网络相关的知识的。

我是敖丙,你知道的越多,你不知道的越多,我们下期见!

人才们的  【三连】 就是敖丙创作的最大动力,如果本篇博客有任何错误和建议,欢迎人才们留言!

更多相关免费学习推荐:mysql教程(视频)

以上就是MySQL索引能让查询效率提高这么多原因是?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/360388.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
积极开拓国内外市场,智微智能2024年预盈1.05亿元-1.35亿元
上一篇 2025年11月6日 02:38:57
英雄联盟崔丝塔娜拜访任务全攻略:三线索速通秘籍
下一篇 2025年11月6日 02:38:58

相关推荐

  • mysql索引的类型和作用有哪些

    MySQL常见索引类型包括:1. 普通索引用于加速查询;2. 唯一索引确保列值唯一;3. 主键索引为唯一非空且自动创建聚簇索引;4. 聚簇索引决定数据物理存储顺序,每表仅一个;5. 非聚簇索引保存主键值,需回表查询;6. 覆盖索引避免回表提升性能;7. 联合索引遵循最左前缀原则;8. 全文索引支持文…

    2026年9月21日
    200
  • MySQL索引是什么_如何通过索引提升查询性能?

    MySQL索引是什么_如何通过索引提升查询性能?MySQL索引是什么_如何通过索引提升查询性能?MySQL索引是什么_如何通过索引提升查询性能?MySQL索引是什么_如何通过索引提升查询性能?

    索引通过排序+查找结构提升查询速度,适合加索引的字段包括where条件、join连接、order by和group by中的字段,但唯一值少、数据量小或频繁更新的字段不适合。常见误区有索引失效、模糊查询左侧通配符、联合索引顺序错误、冗余索引等。可通过explain命令查看索引使用情况,定期清理无用索…

    2026年9月20日 用户投稿
    000
  • MySQL索引覆盖查询优化策略_MySQL提高查询效率技巧

    MySQL索引覆盖查询优化策略_MySQL提高查询效率技巧MySQL索引覆盖查询优化策略_MySQL提高查询效率技巧MySQL索引覆盖查询优化策略_MySQL提高查询效率技巧MySQL索引覆盖查询优化策略_MySQL提高查询效率技巧

    mysql索引覆盖查询优化是指查询所需的所有字段都包含在索引中,从而避免回表读取数据行。1. 索引覆盖能显著提升查询速度,减少磁盘io操作;2. 使用explain命令判断是否使用索引覆盖,若extra列为using index则表示命中;3. 创建索引时应包含所有查询字段,并合理安排字段顺序;4.…

    2026年9月20日 用户投稿
    000
  • MySQL索引如何选择合适的字段_避免索引冗余和重复?

    MySQL索引如何选择合适的字段_避免索引冗余和重复?MySQL索引如何选择合适的字段_避免索引冗余和重复?MySQL索引如何选择合适的字段_避免索引冗余和重复?MySQL索引如何选择合适的字段_避免索引冗余和重复?

    选择合适的mysql索引字段并避免冗余,核心在于平衡查询效率与写入性能。1. 优先考虑高选择性字段(如用户id、订单号),因其能快速定位少量数据行;2. 索引where、join、order by、group by子句中频繁使用的字段,以减少扫描行数;3. 使用小而简单的数据类型(如int、date…

    2026年9月8日 用户投稿
    100
  • MySQL索引失效的原因有哪些_该如何排查?

    MySQL索引失效的原因有哪些_该如何排查?MySQL索引失效的原因有哪些_该如何排查?MySQL索引失效的原因有哪些_该如何排查?MySQL索引失效的原因有哪些_该如何排查?

    索引失效的主要原因有:1.没有正确创建索引;2.查询语句写法不当;3.索引区分度低;4.隐式类型转换;5.联合索引未使用第一列;6.数据量太小。排查方法是通过explain查看执行计划,关注key、type和extra字段。优化建议包括检查sql写法、合理设计索引、增加覆盖索引、定期分析表统计信息以…

    2026年9月7日 用户投稿
    100
  • 详解MySQL索引的底层实现原理

    MySQL索引的底层实现原理 一、前言二、索引类型1、Hash索引2、BTree索引和B+Tree索引(1)BTree索引(2)B+Tree索引(3)B+Tree对比BTree优点:3、全文索引 相关免费学习推荐:mysql视频教程 一、前言 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也…

    2026年9月5日
    100
  • MySQL索引选择性与性能关系_MySQL高效查询索引设计

    MySQL索引选择性与性能关系_MySQL高效查询索引设计MySQL索引选择性与性能关系_MySQL高效查询索引设计MySQL索引选择性与性能关系_MySQL高效查询索引设计MySQL索引选择性与性能关系_MySQL高效查询索引设计

    mysql索引选择性是索引列中不同值与总行数的比值,决定了索引的查询效率。1. 高选择性列(如用户id、邮箱)应优先建立索引,能快速缩小数据范围;2. 合理使用联合索引,遵循最左前缀原则,提升查询效率;3. 利用覆盖索引避免回表查询,提高性能;4. 避免对低选择性列(如性别、状态)单独建索引;5. …

    2026年9月4日 用户投稿
    200
  • MySQL索引原理与实战优化_提升查询性能的关键技术解析

    MySQL索引原理与实战优化_提升查询性能的关键技术解析MySQL索引原理与实战优化_提升查询性能的关键技术解析MySQL索引原理与实战优化_提升查询性能的关键技术解析MySQL索引原理与实战优化_提升查询性能的关键技术解析

    mysql索引类型包括b-tree、哈希、全文索引等,适用于不同查询场景。1.b-tree索引以树状结构存储数据,适合范围查询和排序;2.哈希索引适用于等值查询,但不支持范围查询;3.全文索引用于文本搜索。选择索引需考虑查询需求、数据类型及维护成本。索引失效常见原因包括使用函数、表达式、or条件不当…

    2026年8月28日 用户投稿
    200
  • c++如何实现一个简单的B树_c++数据库与文件系统核心数据结构

    B树是一种自平衡多路搜索树,用于数据库和文件系统中高效管理磁盘I/O。1. 每个节点可含多个关键字和子节点指针,根节点至少两子节点(非叶子),所有叶子同层。2. 节点关键字数在t-1到2t-1之间,内部节点最多2t子节点,t为最小度数。3. 使用模板类实现节点结构,固定数组模拟磁盘块,支持泛型键值。…

    2025年12月19日
    000
  • mysql索引如何优化查询_PHP中利用索引优化mysql查询的技巧

    答案是合理设计并维护索引能显著提升MySQL查询性能。需根据查询场景选择B-Tree、哈希或组合等索引类型,针对WHERE、ORDER BY等条件创建索引,并遵循最左前缀原则;在PHP中利用EXPLAIN分析执行计划,避免函数操作、隐式转换导致索引失效,定期通过慢查询日志和索引监控优化冗余,确保索引…

    2025年12月12日
    000
  • MySQL索引失效的原因是什么?一个案例详解

    MySQL索引失效:一个案例研究 本文通过一个实际案例,深入探讨MySQL索引失效的原因及解决方法。 场景描述 我们有一个名为ns_delivery_shop的表,其结构如下: CREATE TABLE `ns_delivery_shop` ( `id` INT(10) UNSIGNED NOT N…

    2025年12月12日
    200
  • MySQL索引失效:为何shop_id索引在特定条件下失效?

    MySQL索引失效案例分析 本文记录并分析一个MySQL索引失效的案例。 表结构 以下为ns_delivery_shop表的结构定义: CREATE TABLE `ns_delivery_shop` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `…

    2025年12月11日
    100
  • MySQL索引失效:为何`shop_id`索引在数据量增多后失效?

    MySQL索引失效案例分析 本文分析一个实际案例,探讨MySQL索引失效的现象及原因。 数据库表结构如下: CREATE TABLE `ns_delivery_shop` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `goods_id` INT(…

    2025年12月11日
    000
  • MySQL索引失效:为什么shop_id索引在特定查询条件下失效?

    MySQL索引失效场景分析 本文分析一个MySQL索引失效的案例,并探讨其原因。 数据库表结构如下: CREATE TABLE `ns_delivery_shop` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `goods_id` INT(10)…

    2025年12月10日
    100
  • MySQL索引失效:当数据占比超过一定阈值后,索引为什么失效?

    MySQL索引失效:数据占比过高引发的性能问题 MySQL索引是提升数据库查询效率的关键,但某些情况下索引会失效,导致查询性能急剧下降。本文将分析一个常见的索引失效场景:高数据占比导致索引失效。 问题:索引失效的特定条件 假设一个数据表包含shop_id索引。当查询shop_id = 1时,索引起作…

    2025年12月10日
    000
  • 如何在mysql中分析索引命中率

    如何在mysql中分析索引命中率如何在mysql中分析索引命中率如何在mysql中分析索引命中率如何在mysql中分析索引命中率

    通过EXPLAIN、慢查询日志、performance_schema和状态变量可评估MySQL索引使用情况:1. EXPLAIN的type、key、rows和Extra字段显示单条SQL索引命中详情;2. 慢查询日志中Rows_examined大但返回行少的语句可能未有效使用索引;3. perfor…

    2025年12月6日 用户投稿
    100
  • mysql如何查看表的索引顺序 mysql表索引字段顺序查看教程

    要查看mysql表的索引字段顺序,最直接的方法是使用show index from your_table_name命令或查询information_schema.statistics表,其中seq_in_index字段明确指示了各字段在索引中的排列顺序,从1开始递增,通过这两种方式可清晰了解复合索引…

    2025年12月3日
    000
  • MySQL前缀索引导致的慢查询

    MySQL前缀索引导致的慢查询MySQL前缀索引导致的慢查询MySQL前缀索引导致的慢查询MySQL前缀索引导致的慢查询

    前端时间跟一个DB相关的项目,alanc反馈有一个查询,使用索引比不使用索引慢很多倍,有点毁三观。所以跟进了一下,用explain,看 前端时间跟一个db相关的项目,alanc反馈有一个查询,使用索引比不使用索引慢很多倍,有点毁三观。所以跟进了一下,用explain,看了看2个查询不同的结果。 不用…

    2025年12月2日 用户投稿
    000
  • mysql索引学习教程_MySQL

    在mysql 中,索引可以分为两种类型 hash索引和 btree索引。 什么情况下可以用到B树索引? 1.全值匹配索引 比如: orderID=”123” 2.匹配最左前缀索引查询 比如:在userid 和 date字段上创建联合索引。那么如果输入 userId作为条件,那么这个use…

    2025年12月2日
    100
  • 如何使用mysql索引_mysql索引操作方法解析

    如何使用mysql索引_mysql索引操作方法解析如何使用mysql索引_mysql索引操作方法解析如何使用mysql索引_mysql索引操作方法解析如何使用mysql索引_mysql索引操作方法解析

    答案:MySQL索引可提升查询效率,需合理创建、查看、修改和删除。创建支持建表时定义或使用CREATE INDEX、ALTER TABLE添加;唯一索引用UNIQUE,主键自动创建;复合索引遵循最左前缀原则。通过SHOW INDEX、SHOW CREATE TABLE或information_sch…

    2025年12月2日 用户投稿
    000

发表回复

登录后才能评论
关注微信