索引大作战

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

索引的分类

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

  • 按照数据结构分类: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...

相关推荐
gwcgwcjava2 分钟前
[时序数据库-iotdb]时序数据库iotdb的安装部署
数据库·时序数据库·iotdb
SHUIPING_YANG17 分钟前
根据用户id自动切换表查询
java·服务器·数据库
爱吃烤鸡翅的酸菜鱼29 分钟前
IDEA高效开发:Database Navigator插件安装与核心使用指南
java·开发语言·数据库·编辑器·intellij-idea·database
超奇电子33 分钟前
阿里云OSS预签名URL上传与临时凭证上传的技术对比分析
数据库·阿里云·云计算
神仙别闹1 小时前
基于C#+SQL Server实现(Web)学生选课管理系统
前端·数据库·c#
m0_653031361 小时前
PostgreSQL技术大讲堂 - 第97讲:PG数据库编码和区域(locale)答疑解惑
数据库·postgresql
会编程的林俊杰1 小时前
MySQL中的锁有哪些
数据库·mysql
cts6181 小时前
Milvus分布式数据库工作职责
数据库·分布式·milvus
周胡杰1 小时前
鸿蒙加载预置数据库-关系型数据库-如何读取本地/预制数据库
数据库·华为·harmonyos·鸿蒙
布朗克1681 小时前
java常见的jvm内存分析工具
java·jvm·数据库