索引大作战

在日常工作中,对于慢查询的治理方法之一就是增加索引,索引的使用和学习在开发中是比较重要的内容,希望这篇文章能够彻底的梳理清楚。

索引的分类

索引的本质其实是一种数据结构,索引是在存储引擎层而不是在服务层实现的,所以没有统一的索引标准。其分类可以按照数据结构去分类,也可以按照物理存储进行分类,如下所示:

  • 按照数据结构分类:B+Tree 索引、Hash 索引和 Full-text 索引
  • 按照物理存储分类:聚集型索引和非聚集型索引
  • 按照逻辑分类:主键索引、唯一索引、联合索引

以下将重点介绍 B+Tree 索引、Hash 索引、聚集型索引和非聚集型索引

B+Tree 索引

一般我们说索引如果没有特指就是说 B+Tree 索引。基本上所有的存储引擎都支持它,InnoDB 和 MyISAM 存储引擎默认是 B+Tree 索引。

为什么默认使用 B+Tree 数据结构,而不是 B-Tree 或者是红黑树等数据结构?我们先看下 B+Tree 的数据结构

  1. B-Tree 索引非叶子节点存储数据,而 B+Tree 索引叶子结点不存储数据,只有在叶子结点存储数据,相对来说,相同层级存储的索引更多。相同也比红黑树的层级要低,层级低代表次数更少的 I/O 操作。
  2. 叶子结点采用连环式数据结构,可以进行范围查找

Hash 索引

Memory 存储引擎默认是 Hash 索引。Hash 索引的原理是给某列增加索引时,将这列数据进行 Hash 计算得到 Hash 值排列到 Hash 数组中,Hash 索引可以一次性定位到数据,其效率很高。Hash 索引虽然不需要多次进行磁盘 IO,但其也有一些缺点:

  1. 不能进行范围查找。Hash 索引计算的是经过 Hash 处理过的值,只能进行等式比较,不能用于范围查找,比如使用 order by 查询。
  2. 不支持最左匹配(不可使用部分索引进行查询)。每次计算需要扫描整个索引表,最左匹配是可以进行索引前缀进行查询,不必扫描整张索引表。
  3. Hash 索引值大量重复且数据量非常大时,其效率并没有 B+Tree 索引高

聚集型索引和非聚集型索引

聚集型索引和非聚集型索引都是使用 B+Tree 数据结构。

聚集型索引:是指在叶子结点存储完整的行数据,一张表只能有一个聚集型索引,一般是以主键为聚集型索引,如果新建表没有主键,则会创建一个隐含列(唯一)为聚集型索引。

非聚集型索引(辅助索引):叶子结点存储的不是完整的行数据,而是存储一个地址,一般是聚集型索引的地址,通过这个地址能找到聚集型索引,通过聚集型索引再找到完整的行数据。一个表可以有多个非聚集型索引。使用非聚集型索引查询,如果索引中包含查询的列,则直接返回,否则需要回表通过非聚集型索引找到其他查询数据。

联合索引查询

联合索引是指上文中提到的非聚集型索引,也就是辅助索引。联合索引是指索引中包含多个列,举个例子,假如建立索引如下所示:

sql 复制代码
alter table index_example add index idx_union(`name`, `age`, `position`);

数据存储的结构如下所示:

索引的存储会分别按照 name、age 和 position 排序,如果 name 相同,则根据 age 进行排序,name 和 age 相同,则根据 position 进行排序。

应该如何加索引

我们上面介绍了索引包括原理等一些基本情况,在日常开发中,加索引也有一些原则需要注意。以下是加索引的基本原则:

  1. 不要在数据量比较小的表建立索引。在查询时存储引擎会进行判断是否需要使用索引,数据量较小的表可能不会使用索引。
  2. 选择唯一主键索引。如果可以尽量使用主键索引或者唯一索引,将会更快的定位到数据(不需要回表)。
  3. 为经常需要排序、分组和联合操作的字段建立索引。group By、order by、distinct 和 union 等查询操作。
  4. 加索引要满足最左匹配原则。
  5. 尽量选择区分度高的字段增加索引。性别字段就不适合增加索引,不重复的比例越大,扫描的行数越少。索引是根据字段进行排序,0 和 1 的区别不大。
  6. 对字段使用函数不会走索引。

segmentfault.com/a/119000003...

www.cnblogs.com/hld123/p/14...

blog.csdn.net/weixin_4001...

github.com/wardseptemb...

相关推荐
钢铁男儿15 分钟前
C# 接口(什么是接口)
java·数据库·c#
__风__1 小时前
PostgreSQL kv(jsonb)存储
数据库·postgresql
Databend1 小时前
Databend 产品月报(2025年6月)
数据库
Little-Hu2 小时前
QML TextEdit组件
java·服务器·数据库
保持学习ing4 小时前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
宇钶宇夕5 小时前
EPLAN 电气制图:建立自己的部件库,添加部件-加SQL Server安装教程(三)上
运维·服务器·数据库·程序人生·自动化
爱可生开源社区5 小时前
SQLShift 重磅更新:支持 SQL Server 存储过程转换至 GaussDB!
数据库
贾修行5 小时前
SQL Server 空间函数从入门到精通:原理、实战与多数据库性能对比
数据库·sqlserver
傲祥Ax6 小时前
Redis总结
数据库·redis·redis重点总结
一屉大大大花卷6 小时前
初识Neo4j之入门介绍(一)
数据库·neo4j