【MySQL实战45讲笔记】基础篇——深入浅出索引(上)

系列文章

基础篇——MySQL 的基础架构
基础篇——redo log 和 binlog
基础篇——事务隔离


目录

  • 系列文章
  • 深入浅出索引(上)
    • 4.1 索引的常见模型
    • 4.2 InnoDB 的索引模型
    • 4.3 索引维护
    • 4.4 思考:为什么要重建索引以及如何做?


深入浅出索引(上)

索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。我们从小就用的汉语字典里面的声母查询方式就是聚簇索引, 偏旁部首就是二级索引,偏旁部首+笔画就是联合索引。同样,对于数据库的表而言,索引其实就是它的“目录”。

4.1 索引的常见模型

  1. 哈希表:它是一种以键 - 值(key-value)存储数据的结构。把值放在数组里,用一个哈希函数把 key 换算成一个确定的位置,然后把 value 放在数组的这个位置。如果多个 key 值经过哈希函数的换算,会出现了同一个值,处理这种情况的一种方法是,拉出一个链表。

    哈希表这种结构适用于只有等值查询的场景。因为在哈希表中,数据是根据它们的哈希值散列存储的,这意味着相邻的键值在物理上可能相隔很远。对于区间查询,这种无序性导致无法直接定位到查询区间的起始点和结束点(等值查询就是用等号来匹配查询结果,分为单条件查询、多条件查询,与等值查询对应的是模糊查询、范围查询)。

  2. 有序数组:在等值查询和范围查询场景中的性能就都非常优秀。使用二分法能够快速得到值,时间复杂度是O(log(N))。

    缺点是更新数据的成本高,所以有序数组索引只适用于静态存储引擎,比如要保存的是一些不会再修改的历史数据。

  3. 搜索树:树可以有二叉,也可以有多叉。搜索树的特点就是父节点的左子树所有节点的值小于父节点的值,右子树所有节点的值大于父节点的值。这种结构使得查找操作的时间复杂度可以保持在O(log(N))。

    大多数数据库存储不使用二叉树而是多叉搜索树比如B+树。因为索引不止存在内存中,还要写到磁盘上。二叉树比 n 叉树的高度更高,这就意味着需要更多的磁盘 I/O,时间更长。

4.2 InnoDB 的索引模型

InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的。每一个索引在 InnoDB 里面对应一棵 B+ 树。

根据叶子节点的内容,索引类型分为主键索引和非主键索引

  • 主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)
  • 非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

在查询方面,假设,我们有一个主键列为 ID 的表,表中有字段 k,并且在 k 上有索引。

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

所以,使用非主键索引查询可能会触发回表,因为非主键索引的B+树中只存储着数据的主键索引(上面例子里的ID),我们需要用ID在到主键索引的B+树中查询一遍,找到完整的数据。

4.3 索引维护

B+ 树为了维护索引有序性,在插入新值的时候需要做必要的维护。

因此推荐使用自增主键(NOT NULL PRIMARY KEY AUTO_INCREMENT

  • 从性能角度:自增主键的插入数据模式,正符合了递增插入的场景。这种情况下每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点的分裂。而有业务逻辑的字段做主键,则往往不容易保证有序插入,这样写数据成本相对较高。

  • 从存储空间角度:主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小。

当然也有些场景适合用业务字段直接做主键:

  1. 只有一个索引;
  2. 该索引必须是唯一索引。

这就是典型的KV 场景,这种场景下的数据被存储为键和值之间的映射,适用于只需要通过一个唯一键来访问特定值的场合。

因为没有其他索引,所以不用考虑非聚簇索引(二级索引)空间占用大小问题,并且也不用考虑回表的问题

4.4 思考:为什么要重建索引以及如何做?

当我我们删除了表中的一些行时,这些行只是被标记为“已删除”,而不是真的从索引中物理删除了,因而空间也没有真的被释放回收。 InnoDB的Purge线程会异步的来清理这些没用的索引键和行,但是依然没有把这些释放出来的空间还给操作系统重新使用,因而会导致页面中存在很多空洞。

重建索引是将原始索引在磁盘和内存中都删除,再根据原始数据建立索引,可以将原始索引中由于页分裂等原因造成的数据页的利用率低的问题解决 提高页利用率。

如果要重建一个普通索引k ,可以用下面两个 SQL 语句:

alter table T drop index k;
alter table T add index(k);

但是如果是重建一个主键,就不能通过上面两个命令,因为。不论是删除主键还是创建主键,都会将整个表重建。所以连着执行这两个语句的话,第一个语句就白做了。所以这两个语句,可以用这个语句代替 :

alter table T engine=InnoDB

下面是本篇的思维导图以供参考:

在这里插入图片描述

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

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

相关文章

关于一次开源java spring快速开发平台项目RuoYi部署的记录

关于一次开源java spring快速开发平台项目RuoYi部署的记录 本次因为需要一些练习环境,想要快速搭建一个javaweb 项目作为练习环境,经过查询和实验找到一个文档详细,搭建简单,架构也相对比较新的开源项目RuoYi。 项目介绍&#xf…

Quartus+Nios II for eclipse问题合集

由于对于FPGANIOS II 的工作需要,对工作过程中遇到的问题进行记录,持续更新。 1、BSP directory does not exist: . Stop.Nios II使用过程中遇到的一些问题2_error executing nios2-bsp-generate-files --bsp-di-CSDN博客https://blog.csdn.net/qq_39485…

「OpenCV交叉编译」ubuntu to arm64

Ubuntu x86_64 交叉编译OpenCV 为 arm64OpenCV4.5.5、cmake version 3.16.3交叉编译器 gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu 可在arm或linaro官网下载所需版本,本文的交叉编译器可点击链接跳转下载 Downloads | GNU-A Downloads – Arm Developer L…

基于深度学习的点云分割网络及点云分割数据集

点云分割是根据空间、几何和纹理等特征对点云进行划分,使得同一划分内的点云拥有相似的特征。点云的有效分割是许多应用的前提,例如在三维重建领域,需要对场景内的物体首先进行分类处理,然后才能进行后期的识别和重建。 传统的点…

Excel - VLOOKUP函数将指定列替换为字典值

背景:在根据各种复杂的口径导出报表数据时,因为关联的表较多、数据量较大,一行数据往往会存在三个以上的字典数据。 为了保证导出数据的效率,博主选择了导出字典code值后,在Excel中处理匹配字典值。在查询百度之后&am…

硬件知识 cadence16.6 原理图输出为pdf 网络名下划线偏移 (ORCAD)

1. cadence原理图输出为PDF网络名下划线偏移 生这种情况的原因 1. 设计的原理图图纸大小比正常的 A4图纸大。 2. 打印为PDF 的时候,打印机的设置有问题。 2.cadence原理图输出为 PDF网络名下划线偏移的情况 可以看到上图,网络名往上漂移。 3. 解决办法 …

随机森林(Random Forest)详解

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

对原jar包解压后修改原class文件后重新打包为jar

文章目录 背景三种修改方式1.POM中移除原jar中依赖的历史版本2.原jar它不使用pom依赖而是直接放在源码中再编译使用JarEditor 插件对源码进行修改(推荐)使用java-decompiler反编译后修改源码覆盖原class(不好用-不推荐直接跳过)提醒 参考资料-推荐阅读拓…

PyQt6+pyqtgraph折线图绘制显示

1、实现效果 2、环境: 确认已经安装pyqtgraph的模块,如果没有安装,使用命令安装: pip install pyqtgraph 3、代码实现: 绘制折线函数: import sys import random from PySide6.QtWidgets import QAppl…

Altium Designer学习笔记 1-5 工程创建_元件库创建

基于Altium Designer 23学习版,四层板智能小车PCB 目录 1、工程组成 2、AD工程创建 3、元件库的阻容模型创建 4、IC类的元件库模型创建 5、排针类的元件库模型创建 1、工程组成 主要包括原理图库----原理图----PCB库----PCB 2、AD工程创建 新建工程项目 …

Video Duplicate Finder 快速识别并去除重复的视频和图像!

文章目录 下载 后续升级 Video Duplicate Finder(视频重复查找器)是一款开源的跨平台视频(以及图像)去重软件,通过对比文件内容和特征,快速识别出重复的视频和图像文件,即使是被压缩裁剪过、…

力扣力扣力:860柠檬水找零

860. 柠檬水找零 - 力扣(LeetCode) 需要注意的是,我们一开始是没有任何钱的,也就是说我们需要拿着顾客的钱去找零。如果第一位顾客上来就是要找零那么我们无法完成,只能返回false。 分析: 上来我们先不分…

开源许可协议

何同学推动了开源协议的认识,功不可没,第一次对开源有了清晰的认识,最宽松的MIT开源协议 源自OSC开源社区:何同学使用开源软件“翻车”,都别吵了!扯什么违反MIT

装饰器---python

一、柯里化 概念:将原来接受两个参数的函数变成新的接受一个参数的函数过程,新的函数返回一个以原有第二个参数为参数的函数 例如: 例一 原函数是add(x,y),柯里化的目标是add(x)(y),如何实现呢? 相当于嵌套函数,有闭…

Spring AI 框架使用的核心概念

一、模型(Model) AI 模型是旨在处理和生成信息的算法,通常模仿人类的认知功能。通过从大型数据集中学习模式和见解,这些模型可以做出预测、文本、图像或其他输出,从而增强各个行业的各种应用。 AI 模型有很多种&…

知识见闻 - 数学: 均方根 Root Mean Square

What is Root Mean Square (RMS)? 在统计学上,均方根(RMS)是均方的平方根,而均方是一组数值的平方的算术平均数。均方根也称为二次均值,是指数为 2 的广义均值的一种特例。均方根也被定义为基于一个周期内瞬时值的平方…

基于Spring AI alibaba组件AI问答功能开发示例

基于Spring AI alibaba组件AI问答功能开发示例 功能效果图: http://localhost:9999/ai/test http://localhost:9999/ai/chat?inputai 配置 application.yaml 指定 API-KEY(可通过访问阿里云百炼模型服务平台获取,有免费额度可用。&#x…

Linux - 线程基础

文章目录 1.什么是线程2.线程vs进程3.线程调度4.线程控制4.1 POSIX线程库4.2创建线程4.3线程终止4.4线程等待4.5线程分离 5、线程封装 1.什么是线程 在Linux操作系统中,线程是进程内部的一个执行流。在Linux操作系统下,执行流统称为轻量级进程&#xff0…

5、AI测试辅助-生成测试用例思维导图

AI测试辅助-生成测试用例思维导图 创建测试用例两种方式1、Plantuml思维导图版本 (不推荐)2、Markdown思维导图版本(推荐) 创建测试用例两种方式 完整的测试用例通常需要包含以下的元素: 1、测试模块 2、测试标题 3、前置条件 4、…

PTA编程题:N个数求和

问题描述 思路分析 问题分解 输入处理:将分数拆解为分子和分母,存储并处理。 分数相加规则: 即分子相加、分母相乘。 结果化简:求分数的最大公因数(GCD),将其约分至最简形式。 带分数处理&…