SQL 索引详解(B树、哈希、聚集与非聚集类型对比)

SQL 的索引是一种与表或视图关联、用于加速数据检索的磁盘结构。它按一列或多列建立键值,并以 B 树(行存储实际实现为 B+ 树)等有序结构组织,让数据库不必全表扫描就能快速定位目标行。据 Microsoft Learn 的官方定义,索引是”与表或视图关联、可加快从中检索行的磁盘结构”,索引键存储在 B 树中,使引擎能高效找到对应行。创建 PRIMARY KEY 或 UNIQUE 约束时,SQL Server 等引擎会自动建立相应索引。索引的本质是”空间换时间”——它占用额外存储并在写入时增加维护成本,但能大幅减少磁盘 IO。

一、索引在解决什么问题

没有索引时,查询只能做全表扫描:逐行读取整张表,挑出满足条件的行。据 Microsoft Learn 的查询优化说明,全表扫描会产生大量磁盘 IO,资源消耗高;一旦存在可用索引,优化器会在索引键列中查找,再定位数据行,通常远快于扫表。索引类似书籍目录——先查目录页找到页码,再翻到正文,而不是一页页翻。

二、索引的底层结构

索引的存储结构决定了它能做什么。主流结构有三种:

结构 工作原理 支持的能力 典型使用
B 树 / B+ 树 多叉有序树,键值排序存放 等值、范围、排序、前缀匹配 绝大多数通用索引(InnoDB 默认 B+ 树)
哈希索引 哈希表映射键到行 仅等值查询,极快 内存表、精确匹配
列存储索引 按列而非按行存储 海量数据分析、压缩率高 数据仓库只读负载

据腾讯云开发者社区与 CSDN 的整理,MySQL InnoDB 的默认结构是 B+ 树:非叶子节点只存键、叶子节点存数据并通过链表相连,因此特别适合范围查询。哈希索引不支持范围查询和排序,只做精确匹配。

三、按物理存储:聚集与非聚集

这是最关键的二分法(综合 Microsoft Learn 与多个 MySQL 教程):

聚集索引(Clustered):数据行的物理存储顺序与索引键顺序一致,索引的叶子节点直接保存完整数据行。一张表只能有一个聚集索引,因为数据行本身只能按一种顺序存放。在 InnoDB 中,主键即聚集索引;若无主键,则选第一个唯一非空索引;再无则隐式生成。

非聚集索引(Non-clustered):索引与数据分开存储,叶子节点保存索引键值和行定位符(指向聚集索引键或堆中的行)。一张表可有多个非聚集索引。查询走非聚集索引后,往往还要用定位符”回表”取完整数据,比聚集索引多一次查找。

两者对比:

对比维度 聚集索引 非聚集索引
数据存储 叶子节点即数据本身 叶子节点存键 + 定位符
每表数量 最多 1 个 可有多个
查询路径 直接定位数据 需回表再取数据
写入影响 较大(可能重排) 较小

四、按功能与约束:唯一、主键、普通、全文

据 cnblogs 与 runnerliu 博客的分类:

  • 主键索引:特殊的唯一索引,不允许 NULL,一张表只能有一个,建表时指定或自动创建。InnoDB 中它同时是聚集索引。
  • 唯一索引(Unique):索引列值必须唯一,但允许单个 NULL。据 Microsoft Learn,唯一性既可以是聚集索引的属性,也可以是非聚集索引的属性。
  • 普通索引(Normal):最基础的索引,无唯一约束,一个表可有多个单列索引。
  • 全文索引(Full-text):基于词元的特殊功能索引,由全文引擎维护,用于字符串中的复杂词语搜索。
  • 空间索引(Spatial):针对几何数据类型,加速空间对象运算。
  • 复合索引(组合 / 联合索引):在多个列上建立,遵循最左前缀原则(详见 13138 篇)。

五、特殊类型:筛选、包含列、列存储

Microsoft Learn 还列出几种进阶索引:

  • 筛选索引(Filtered):只索引表中满足过滤谓词的子集,比全表索引更小、维护更轻,适合固定子集查询。
  • 包含列索引(带 INCLUDE):非聚集索引扩展出非键列,使索引本身就能覆盖查询、避免回表。
  • 列存储索引(Columnstore):面向列存储与列处理,数据仓库负载下可达传统行存储约 10 倍查询性能提升与约 7 倍压缩率。

六、创建与删除语法

sql

-- 普通索引
CREATE INDEX idx_name ON users(name);

-- 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

-- 复合索引
CREATE INDEX idx_status_time ON orders(status, create_time);

-- 删除索引
DROP INDEX idx_name ON users;

据 CSDN 的语法示例,PRIMARY KEY 在建表时指定会自动建聚集索引;UNIQUE 约束自动建非聚集唯一索引。

七、索引的两面性

索引不是越多越好。据 cnblogs 的优缺点分析:

  • 优点:加快 WHERE 等值/范围查询、加速 ORDER BY 与 GROUP BY、提升 JOIN 性能、唯一索引保证数据唯一。
  • 缺点:占用额外磁盘/内存空间;INSERT/UPDATE/DELETE 需同步维护索引,拖慢写入;增加维护成本。

经验上,高频查询列、高选择性列、外键列优先建索引;写多读少、低基数列(如性别)则谨慎。

常见问题(FAQ)

一张表能有几个聚集索引?
最多 1 个。数据行物理顺序只有一种,InnoDB 中主键即为聚集索引。

唯一索引和主键索引有何不同?
主键索引不允许 NULL 且每表唯一一个;唯一索引允许单个 NULL,可建多个,两者都可聚集或非聚集。

哈希索引为什么不适合范围查询?
哈希表只做键到行的等值映射,不支持键的顺序遍历,因此范围、排序类查询用不了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
小码农的头像小码农认证作者

相关推荐

返回顶部