MSSQL里各种索引类型到底怎么用,帮你搞懂提高查询速度那些事儿
- 问答
- 2026-01-19 20:44:05
- 2
想象一下,你有一本非常厚的电话簿,但是没有按姓氏排序,也没有按街道名称分类,你要找“张三”的电话,只能从第一页开始一页一页地翻,这得花多长时间?这就是数据库没有索引时的样子,我们称之为“全表扫描”,速度非常慢。
我们给这本电话簿加上索引。
聚集索引:电话簿本身的排序方式
这本电话簿默认就是按“姓氏拼音”排序的,A-Z,这个“姓氏拼音”就是聚集索引,它的特点是:
- 决定了数据真实的物理存储顺序。 数据行就是按照这个索引的键值(比如姓氏)在磁盘上排队的。
- 一张表只能有一个聚集索引。 就像电话簿只能选择一种主要排序方式(要么按姓氏,要么按名字,不能同时两种都作为主要排序)。
- 怎么用? 你会把聚集索引放在最常用于查询、而且顺序性很好的列上。
- 主键(ID列),因为ID通常是自增的,顺序插入很快。
- 日期列,如果你经常按日期范围查询(比如查上个月的订单)。
- 来源参考:微软官方文档将聚集索引描述为表数据的存储基础,决定了数据的物理顺序。
关键点: 因为一张表只能有一个聚集索引,所以选择哪个列来创建需要慎重考虑,如果选错了,比如把一个经常变化的列设为主键(聚集索引),会导致数据行频繁地在磁盘上移动位置,反而降低性能。

非聚集索引:书后面的附录索引
电话簿后面可能还有一个附录,是按“街道名称”排序的,列出了每条街道上所有住户的姓名和对应的页码,这个附录就是一个非聚集索引,它的特点是:
- 它和真实的数据是分开存储的。 就像附录在书的最后面,和正文分开。
- 它只包含索引列的数据和指向真实数据行的“指针”(也叫行定位符)。 在附录里,你看到的是街道名和页码,你需要根据页码再去翻到正文。
- 一张表可以有多个非聚集索引。 你可以同时有“街道索引”、“职业索引”等多个附录。
- 怎么用? 这是提高查询速度最常用的手段,为你经常用在
WHERE子句、JOIN条件、ORDER BY里的列创建非聚集索引。- 给“用户表”的“邮箱”字段加索引,这样用邮箱登录时超快。
- 给“订单表”的“客户ID”加索引,这样查某个客户的所有订单就很快。
- 来源参考:SQL Server技术专家常将非聚集索引比作书籍的目录,通过目录找到主题对应的页码,再翻到该页。
这里有个重要的概念:“键查找”(Key Lookup) 继续用电话簿的例子,如果你用“街道附录”找“人民路123号”的“张三”的电话号码,附录告诉你张三在第50页,你翻到第50页,发现这一页上住了好几个“张三”(张三、张三丰、张三四),你得挨个看哪个是住在“人民路123号”的。 在数据库里,这个过程就叫“键查找”或“RID查找”,当你的非聚集索引包含了过滤条件(街道=人民路123号),但没有包含你想要查询的所有数据(电话号码)时,数据库就得用索引里的“指针”回到真实的数据页(聚集索引)里去把剩下的数据找出来,这个“回表”操作如果次数太多,会很慢。

如何避免讨厌的“键查找”?——覆盖索引
怎么解决上面“键查找”慢的问题呢?很简单,让那个“附录”包含所有你需要的信息。 我们在“街道附录”里,不仅列出街道名和页码,直接把住户的“姓名”和“电话号码”也印在旁边,这样,当你查“人民路123号”的电话时,直接在附录里就看到“张三”和他的电话号码了,根本不需要再翻到正文的第50页。 在数据库里,这就叫“覆盖索引”,意思是:一个非聚集索引包含了查询所需要的所有字段,这个查询会被索引“覆盖”,速度极快,因为数据库不用再去访问真实的数据页了。
- 怎么创建覆盖索引? 有两种方法:
- 在创建索引时使用
INCLUDE子句。 为“街道”创建索引,并把“姓名”和“电话号码”包含进来。INCLUDE进来的列不会用于排序和查找,但会存储在索引的叶子节点,用于直接返回,避免键查找,这是推荐的做法。 - 直接创建一个包含多列的复合索引。 比如索引是(街道,姓名,电话号码),这样这个索引既可以按街道快速查找,也因为包含了电话号码而成为覆盖索引。
- 在创建索引时使用
其他有用的索引类型
- 唯一索引: 这个很好理解,就是要求索引列的值必须是唯一的,主键自动就是唯一索引,你也可以给“身份证号”、“邮箱”这种列创建唯一索引,保证数据不重复,同时也加快了查询速度。
- 筛选索引: 只对一部分数据创建索引,你的订单表99%的订单状态都是“已完成”,你只关心查询“进行中”的订单,那么你可以创建一个筛选索引,只包含“状态=进行中”的数据,这样索引非常小,维护成本低,查询“进行中”订单的速度极快。
- 列存储索引: 这是针对大数据分析(数据仓库)的“大杀器”,它不再是按行存储,而是按列存储,对于那种需要扫描数百万行、但只关心其中几个列的分析查询(计算去年每个产品的销售总额”),列存储索引可以将性能提升十倍甚至百倍,但它不适合频繁增删改的日常业务系统。
总结一下怎么用:
- 主键通常是聚集索引的好选择,但如果不是自增ID或经常范围查询的列,可以考虑其他方案。
- 为高频查询的
WHERE条件列创建非聚集索引。 - 尽量让非聚集索引成为“覆盖索引”,通过
INCLUDE关键字把查询需要的其他列包含进来,这是避免键查找、大幅提升性能的关键技巧。 - 索引不是越多越好,每个索引都会占用空间,并且每次增删改数据时,数据库都需要更新相关的索引,索引太多会降低写入速度,只创建那些真正能带来性能提升的索引。
- 对于大量数据的分析报表,研究一下列存储索引。
理解索引就像理解如何高效地整理书籍和资料,目的就是为了用最快的速度找到你想要的东西,先从非聚集索引和覆盖索引这两个最实用的概念入手,你的查询速度就会有立竿见影的提升。
本文由颜泰平于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/83874.html
