聚簇索引和非聚簇索引——是什么?区别是什么?优缺点?

news/2024/9/28 23:19:36/

是什么?

聚簇索引也叫主键索引,是将索引和数据放在一起,聚簇索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里;找到索引也就找到了数据。

非聚簇索引是指二级索引,也叫辅助索引。通过非聚簇索引可以查到记录对应的主键值,再使用主键的值通过聚簇索引找到要查找的数据。

Innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值。

区别是什么? 

1.数据存储方式:

  • 聚簇索引:表数据按照索引的顺序来存储。即索引的叶子节点包含了完整的数据行。
  • 非聚簇索引索引和数据是分开存储的,索引的叶子节点存储的是指向数据行的指针。

2.主键与索引关系:

  • 聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引。InnoDB 只聚集在同一个页面中的记录。包含相邻键值的页面可能相距甚远。如果你已经设置了主键为聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。
  • 非聚簇索引可以在表的任何列上创建,不限于主键。

3.数据查找效率:

  • 对于主键的查询,聚簇索引查找速度更快,因为直接可以获取到数据。
  • 非聚簇索引需要先通过索引找到指针,再根据指针去查找数据,多了一次查找过程。

4.范围查询性能: (后面有详细介绍)

  • 聚簇索引在范围查询时性能较好,因为数据在物理上是连续存储的。
  • 非聚簇索引在范围查询时可能效率相对较低。

5.插入和删除操作影响:

  • 聚簇索引在插入和删除数据时,可能会导致数据的移动,影响性能。
  • 非聚簇索引相对来说对插入和删除操作的影响较小。

聚簇索引的优势 

  • 查找数据更快:由于行数据和叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快。
  • 聚簇索引适合用在排序的场合,非聚簇索引不适合:

    聚簇索引中,数据是按照索引键的顺序物理存储的。这意味着,如果按照聚簇索引的键进行排序查询,数据库不需要额外的排序操作,因为数据本身已经是有序的。

    例如,有一个订单表,按照订单号建立了聚簇索引。当需要按照订单号升序或降序获取订单信息时,数据库可以直接按照存储顺序读取数据,效率很高。

    而非聚簇索引中,索引的叶子节点存储的是指向数据的指针,数据本身的存储顺序与索引键的顺序无关。当基于非聚簇索引进行排序查询时,数据库首先需要通过索引找到数据的指针,然后再根据指针获取数据,并在内存中进行排序操作。这增加了额外的开销,效率相对较低。

    假设一个客户表,以客户 ID 建立了非聚簇索引,而数据按照注册时间存储。如果要按照客户 ID 排序获取客户信息,数据库需要先通过非聚簇索引找到数据指针,再获取数据并排序。

  • 可以把相关数据保存在一起:

    以电子邮箱为例,如果按照用户 ID 建立了聚簇索引,那么属于同一个用户的所有邮件数据在物理存储上会靠在一起。当您要获取某个用户的全部邮件时,只需要从磁盘读取相对较少的数据页就行。

    但如果没有使用聚簇索引,每个邮件可能在磁盘上随机分布,那么获取每一封邮件都可能需要单独从磁盘读取一次,这会大大增加磁盘操作的次数,降低效率。

非聚簇索引的优势

如果辅助索引使用地址值作为指针,会存在一些问题。当数据库中的行发生移动,比如由于插入或删除操作导致 B+树节点分裂,或者数据页分裂时,原来存储的地址值就可能变得无效或者不准确。为了保持辅助索引的正确性,数据库就需要花费额外的资源和时间去更新这些地址指针,这就增加了辅助索引的维护工作,会影响数据库的性能。

然而,如果辅助索引使用主键作为“指针”,情况就有所不同(实际就是这个)。虽然这样做会使得辅助索引占用更多的空间,因为主键通常比地址值占用更多字节。但换来的好处是显著的。

在 InnoDB 存储引擎中,行的位置实际上是通过 16K 的 Page 来定位的。随着数据库中数据的不断修改,比如频繁的插入、删除操作,可能会导致前面提到的 B+树节点分裂以及 Page 的分裂。这就会使得行的实际存储位置发生变化。

但因为辅助索引使用的是主键值作为指针,只要主键值本身不变,无论主键所在的 B+树节点如何变化,辅助索引都无需更新这个“指针”。

再进一步说,当使用聚簇索引时,由于聚簇索引决定了数据的物理存储顺序,并且主键是聚簇索引的一部分。所以,即使聚簇索引中的主键 B+树节点发生了变化,只要主键值不变,辅助索引树就能够保持稳定,不受这些变化的影响。


http://www.ppmy.cn/news/1531101.html

相关文章

宠物寄养系统小程序的设计

管理员账户功能包括:系统首页,个人中心,宠主管理,宠物种类管理,寄养环境管理,宠物寄养管理,系统管理 微信端账号功能包括:系统首页,寄养环境,我的 开发系统…

Python办公自动化教程(003):PDF的加密

【1】代码 from PyPDF2 import PdfReader, PdfWriter# 读取PDF文件 pdf_reader PdfReader(./file/Python教程_1.pdf) pdf_writer PdfWriter()# 对第1页进行加密 page pdf_reader.pages[0]pdf_writer.add_page(page) # 设置密码 pdf_writer.encrypt(3535)with open(./file/P…

Java面试篇基础部分- 锁详解

可重入锁 可重入锁也叫作递归锁,是指在同一个线程中,在外层函数获取到该锁之后,内存的递归函数还可以获取到该锁。在Java语言环境下,ReentrantLock和Synchroinzed都是可重入锁的代表。 公平锁与非公平锁 公平锁(Fair Lock)是指在分配锁之前检查是否有线程在排队等待获取…

Spring @Import

Import是Spring框架提供的注解org.springframework.context.annotation.Import,可以通过条件配置,选择性的注入哪些Bean到Spring IOC容器中; 一 Import注Bean到Spring容器 直接使用Import注解将Bean对象注入到容器 public class OrderChoi…

学习react小记

系列文章目录 目录 系列文章目录 前言 一、关于Hook 1、useEffect 1.1 如果在 useEffect 中没有声明第二个参数(依赖项数组),则会导致 useEffect 的行为有所不同。具体来说,以下是几种可能的情况: 1.1.1 没有依赖项数…

堆的数组实现

目录 一、堆 二叉树的顺序结构 堆的概念及结构 1.概念 2.堆的分类 (1)大堆 (2)小堆 二、利用数组(顺序结构)实现堆的过程 1.利用数组实现堆的思路 2.堆是用数组实现的,在数组中通过双亲找自己左右孩子、通过左右孩子找自己双亲的思路 2.1.思路 2.2.孩子与…

【Kubernetes】常见面试题汇总(二十九)

目录 81.简述你知道的几种 CNI 网络插件,并详述其工作原理。K8s 常用的CNI网络插件(calico && flannel),简述一下它们的工作原理和区别。 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题&#xff…

uniapp webview清理缓存

uniapp webview清理缓存 后端服务器配置,JS/CSS文件的缓存时间为 :-1s location ~ .*.(js|css)?$ { expires -1s; error_log off; }前端打开webview页面处: //ios 禁用缓存,测试生效!! let cache1 plus.…