MySQL索引

目录

什么是索引

索引的作用

索引的使用

查询索引

创建索引

删除索引

索引底层数据结构实现


什么是索引

**索引(index)**是用于提高查询性能的数据结构。可以大大加快数据检索速度,但会增加写入和存储的开销

索引的作用

索引的作用类似于一本书的目录

当需要找到找到书中某个章节的所在位置时,就可以查找目录,方便我们快速定位

因此,索引的特点:

(1)加快查询速度

(2)索引需要存储一定的索引结构,因此会存在额外的存储开销

(3)当我们需要进行 新增、删除 和 修改 的时候,也需要针对索引进行更新。对索引进行更新,也是额外的开销

因此,当我们需要根据条件进行查找时,索引就能帮助我们检索数据、快速定位,提升性能

但当我们需要进行 新增、删除 和 修改 时,就需要修改(维护)索引,此时就会降低性能

因此,在适用索引之前需要考虑以下几点:

(1)数据量比较大,且需要经常对这些列进行条件查询

(2)该数据库表的插入、更新 和 修改 操作的频率低

(3)索引会占用额外的磁盘空间

若满足以上条件,则可以考虑对表中字段创建索引,以提高效率

反之,若非条件查询列,或经常执行 插入、修改 和 删除 操作,或磁盘空间不足,则不考虑创建索引

索引的使用

查询索引

show index from table;

例如:

我们创建一张学生表:

drop table if exists student;

create table student (

id int primary key,

name varchar(10) unique,

chinese int,

math int,

english int

);

查看索引:

show index from student;

'

当创建 主键约束(primary key)、唯一约束(unique)和 外键约束(foreign key)时,会自动创建对应列的索引

一个表的索引可以有多个,每个索引都是根据某个具体的列来展开的,后续按照这个列来进行查询时才能提高效率

就像字典,包含了多个目录,可以根据拼音、部首、笔画...等不同目录来进行检索

创建索引

对于非主键、非唯一约束、非外键的字段,可以创建普通索引

create index 索引名 on table_name(列名);

为 chinese 字段创建普通索引:

create index index_student_chinese on student(chinese);

创建成功:

由于此时数据表为空(或在数据比较少的情况下),此时创建索引就没有任何问题,但是如果表本身就有很多数据,此时创建索引操作就会触发大量硬盘IO,数据库就可能会挂掉

删除索引

drop index 索引名 on table_name;

删除 chinese 的索引:

drop index index_student_chinese on student;

与添加索引一样,删除索引也是一个危险操作

因此,当我们需要创建索引时,一定要在建表时就规划好

索引底层数据结构实现

索引其实是通过额外的数据结构,来针对表中的数据进行重新组织,不同的数据结构适用于不同类型的查询和场景

那么,索引是怎样来对数据进行重新组织呢?

一般使用 B+ 树来实现索引,在了解 B+ 树之前,我们先来了解 B 树

B 树(B-树 B-Tree) :B 树是一种自平衡 的树数据结构,可以保持数据的有序性并允许以对数时间复杂度进行搜索、插入和删除操作

我们通过一个具体的例子来进一步理解:

B树是一颗N叉搜索树 ,一个节点上包含N个key,按照顺序排列,N个值划分出了 N + 1 个区间:

由于是N叉树,相比于二叉树,同样的高度,能表示的元素就会多很多,这样当我们使用B树进行查询时,比较的次数就会比二叉搜索树少很多

且由于节点内的值是有序的,就能够在节点内部进行二分查找,从而加速搜索过程

更重要的是,同一个节点中的key都是一次硬盘IO读取出来的,即使同一个节点上的比较次数增加了,但是硬盘IO的次数少了(一次硬盘IO 大概相当于 内存 中的1万次比较)

接着,我们来看B+树

B+树(B+ Tree) :B+树是B-树的一种变体,在B树的基础上做出了改进,其所有的值都存储在叶子节点中,而非叶子节点只存储键值,用于引导搜索

B+ 树也是一颗N叉搜索树,每个节点包含多个key,N 个 key 划分出 N 个区间:

其中,每个节点的 N 个 key 中,都会存在一个最大值(或最小值)

每个节点中的 key,都会在子树重复出现,这样重复出现,带来的好处是所有数据都包含在叶子节点这一层中

叶子节点之间使用链式结构相连

所有的数据出现在叶子节点中,当查询任何一个元素时,都需要从根节点查询到叶子节点,过程中经过的硬盘IO次数是一样的,因此,使用 B+ 树查询的时间是稳定的

将叶子节点连接起来,在进行范围查询时,就会快很多

例如:

进行查询范围:between 15 and 50 之间的数据:

此时,只需要查找到最开头的数据,再沿着链表向后遍历,即可找到所有满足条件的数据:

相关推荐
l1t35 分钟前
DeepSeek总结的DuckDB 2.0.0 中的隐藏亮点
大数据·数据库·duckdb
爱吃火鸡面呀37 分钟前
MySQL、ClickHouse、Doris、Hive、Spark SQL、Flink SQL 选型对比:优点、缺点与面试话术
hive·mysql·clickhouse
程序员塔塔喵1 小时前
【MySQL篇|第八篇】索引底层实现
数据库·mysql·adb·索引
updayday8541 小时前
电脑换了硬盘、加了内存,资产台账却没更新 - Ping64 硬件资产管理
大数据·网络·数据库·安全·智能路由器
hhhjhl1 小时前
mime-types 跨端三方库仓颉适配全流程
数据库
广州智造1 小时前
Radioss中破坏模型FAILTAB1的详细介绍
数据库·人工智能·算法·机器学习·仿真软件·radioss
李兆龙的博客1 小时前
从一到无穷大 #101:SSD 的工作原理——从 NAND 到数据库读写
数据库·ssd·存储
吹什么轩1 小时前
MySQL 内置函数全景:日期 / 字符串 / 数学 / 其他,一次讲透(附索引杀手排查)
java·数据库·面试
CS创新实验室2 小时前
改了模型,数据库为什么能自动跟上?——Django 迁移(migrations)的底层
数据库·django·sqlite
编码追梦人2 小时前
基于 ESP32-S3 的便携式多参数环境监护仪设计:从硬件选型到 FreeRTOS 多任务落地
数据库·单片机·嵌入式硬件·mongodb·esp32·freertos·低功耗设计