首页 > 其他分享 >深入浅出索引(上)

深入浅出索引(上)

时间:2025-01-20 09:04:21浏览次数:1  
标签:插入 深入浅出 节点 索引 主键 查询 ID

1.什么是数据库索引,索引是干什么用的?

对于数据库的表而言,索引其实就是它的“目录”。

2.索引的三种实现方式?(暂时介绍3种)

①哈希表索引:哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。哈希的思路很简单,把值放在数组里,用一个哈希函数把key 换算成一个确定的位置,然后把 value 放在数组的这个位置。

哈希表索引的局限性:如果多个Key通过hash函数计算出同一值出现冲突时,只能通过拉链法来进行存储。如果你现在要找值在 [Min, Max] 这个区间的所以值,就必须全部扫描一遍。所以,哈希表这种结构适用于只有等值查询的场景

②有序数组作为索引有序数组在等值查询和范围查询场景中的性能就都非常优秀。但是有序数组在插入新的数据时效率非常低,所以有序数组仅适合静态存储引擎。

③二叉搜索树作为索引::每个节点的左儿子小于父节点,父节点又小于右儿子。为了维持 O(log(N)) 的查询复杂度,你就需要保持这棵树是平衡二叉树。为了做这个为了维持 O(log(N)) 的查询复杂度,你就需要保持这棵树是平衡二叉树。为了做这个。

二叉搜索树的局限性:你可以想象一下一棵 100 万节点的平衡二叉树,树高 20。一次查询可能需要访问 20 个数据块。在机械硬盘时代,从磁盘随机读一个数据块需要 10 ms 左右的寻址时间。也就是说,对于一个 100 万行的表,如果使用二叉树来存储,单独访问一个行可能需要 20 个 10ms 的时间,这个查询可真够慢的。(sum up:二叉搜索数的树高太高了,数据量上来之后,很多时间都被磁盘I/O给耽误了。如果要改进,可以从减少树高的角度上下手)

3.那MySQL引擎InnoDB用的什么数据结构作为索引呢?

在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。又因为前面我们提到的,InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+树中的。

image-20250120081723491

该图是某表的InnoDB的索引结构

从图中不难看出,根据叶子节点的内容,索引类型分为主键索引和非主键索引。

主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引

非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引

根据上面的索引结构说明,我们来讨论一个问题:基于主键索引和普通索引的查询有什么区别?

如果语句是 select * from T where ID=500,即主键查询方式,则只需要搜索 ID 这棵B+ 树;

如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

3.那InnoDB中的索引是如何维护的?

​ B+ 树为了维护索引有序性,在插入新值的时候需要做必要的维护。以上面这个图为例,如果插入新的行 ID 值为 700,则只需要在 R5 的记录后面插入一个新记录。如果新插入的 ID值为 400,就相对麻烦了,需要逻辑上挪动后面的数据,空出位置。
​ 而更糟的情况是,如果 R5 所在的数据页已经满了,根据 B+ 树的算法,这时候需要申请一个新的数据页,然后挪动部分数据过去。这个过程称为页分裂。在这种情况下,性能自然会受影响。

​ 除了性能外,页分裂操作还影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体空间利用率降低大约 50%。

​ 当然有分裂就有合并。当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。合并的过程,可以认为是分裂过程的逆过程。

在什么场景下建表应该用自增主键?

你可能在一些建表规范里面见到过类似的描述,要求建表语句里一定要有自增主键。当然事无绝对,我们来分析一下哪些场景下应该使用自增主键,而哪些场景下不应该。

性能角度考虑

插入新记录的时候可以不指定 ID 的值,系统会获取当前 ID 最大值加 1 作为下一条记录的ID 值。也就是说,自增主键的插入数据模式,正符合了我们前面提到的递增插入的场景。每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点的分裂。而有业务逻辑的字段做主键,则往往不容易保证有序插入,这样写数据成本相对较高。

存储空间的角度上考虑

除了考虑性能外,我们还可以从存储空间的角度来看。假设你的表中确实有一个唯一字段,比如字符串类型的身份证号,那应该用身份证号做主键,还是用自增字段做主键呢?

由于每个非主键索引的叶子节点上都是主键的值。如果用身份证号做主键,那么每个二级索引的叶子节点占用约 20 个字节,而如果用整型做主键,则只要 4 个字节,如果是长整型(bigint)则是 8 个字节。

显然,主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小。

所以,从性能和存储空间方面考量,自增主键往往是更合理的选择。

有没有什么场景适合用业务字段直接做主键的呢?还是有的。比如,有些业务的场景需求是这样的:

  • 只有一个索引;
  • 该索引必须是唯一索引

其实这就是典型的KV场景。

由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小的问题。这时候我们就要优先考虑上一段提到的“尽量使用主键查询”原则,直接将这个索引设置为主键,可以避免每次查询需要搜索两棵树。

标签:插入,深入浅出,节点,索引,主键,查询,ID
From: https://www.cnblogs.com/qiwenforever/p/18680687

相关文章

  • 每次看到你,我的心就像OSPF一样,自动选择最短路径。基于华为ENSP的OSPF协议深入浅出[既
    本篇技术博文摘要......
  • 博客索引
    仅展示施工中和施工完毕的文章数学组合数学组合数学学习笔记(一)(2024.7.3)(施工完毕):组合数基本知识,二项式定理,卢卡斯定理,错位全排列。组合数学学习笔记(二)(2024.7.4)(施工中):鸽巢原理,容斥原理多项式多项式学习笔记(一)(2024.7.6)(施工完毕):暴力多项式计算,快速傅里叶变换,快速数论变换多项式......
  • 一文让你对mysql索引底层实现明明白白
    作者:京东零售韩航云开篇:图片是本人随笔画的,有点粗糙,望大家谅解,如有不对的地方,请联系本人,感谢一、索引到底底是什么.索引是帮助mysql高效获取数据的排好序的数据结构.索引是存储在文件里的.数据结构:二叉树HASHBTREE  如果没有索引的话,循环一条一条的找,找一次就是一......
  • 热门开源Ai搜索引擎对比分析
    汇总lepton●项目地址:https://github.com/leptonai/search_with_lepton●简介:比较早期的AiSearch,由贾扬清团队项目开源,整个项目含前后端在内仅需不到500行代码。●搜索引擎:支持两种默认搜索引擎:Bing和Google。●LLM:官方提供的API,可自行替换其他厂商API。●其他:提供......
  • 命中索引一定能提高查询速度吗?
    命中索引一定能提高查询速度吗?目录命中索引一定能提高查询速度吗?目录索引的基本原理索引命中与查询性能查询复杂性数据量与索引选择性更新与维护成本过多的索引何时索引能提高查询速度?简单查询高选择性字段适当的索引类型结论答案是否定的,在实际项目中我曾踩过这......
  • Pandas数据重命名:列名与索引为标题
    目录一、引言二、Pandasrename方法简介三、列名重命名3.1使用字典进行列名重命名3.2使用函数进行列名重命名四、索引重命名4.1使用字典进行索引重命名4.2使用函数进行索引重命名五、同时重命名列名和索引六、原地修改与返回新对象七、处理MultiIndex(多级索引)......
  • 初识ES ---倒排索引
    正向索引:mysql 倒排索引:elasticsearch采用倒排索引:文档(document):每条数据就是一个文档。词条(term):文档按照语义分成的词语(中文按照中文语义分)。词条不能重复。 eg:会对用户输入的关键字数据进行分词华为手机-》分词:华为手机 可以看出:正向索引:是根据关键字直......
  • 深入浅出Node.js-4(详解网络通信)
    这篇文文章我们将详细讲解网络通信的整个流程当我们在浏览器中输入地址到浏览器返回页面给我们这中间究竟发生了什么?总的来说有以下六个点网络模型浏览器与服务器建立连接(三次握手)浏览器发送请求报文(HTTP协议)服务器返回响应报文(HTTP协议)浏览器渲染页面(看我之前的浏......
  • 深入浅出Node.js-5(Webpack模块打包工具)
    Webpack模块打包工具webpack_demo工程化从0-1配置完整版.rar本章节通过从0到1的方式来配置出一个【工程化】项目结构,让大家了解Node+Webpack是如何做工程化配置的。学完本章节后,你能知道工程化的基本原理,为将来使用vue的工程化开发打下基础Webpack基本概念Webpack 是一......
  • 如何解决使用 SQL Server 管理器远程操作数据库时出现“索引超出了数组界限 (Microsof
    问题描述当您使用SQLServerManagementStudio(SSMS)远程连接并操作数据库时,可能会遇到以下错误提示:“索引超出了数组界限(Microsoft.SqlServer.Smo)”。这个错误通常发生在尝试执行某些特定操作(如查询、修改表结构等)时。该问题不仅影响工作效率,还可能导致数据操作失败。错......