You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何查询带聚集索引的表时出现Clustered Index Scan而非Table Scan?

问题背景

我有两个简单表:一个无任何索引,另一个仅在id字段上设置了主键和聚集索引:

CREATE TABLE [dbo].[MyTableWithoutPk]([id] [int] NOT NULL, [category_id] int NULL)

CREATE TABLE [dbo].[MyTableWithPk]   ([id] [int] NOT NULL, [category_id] int NULL, 
  CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ([id] ASC))

对无主键表执行以下带WHERE子句的查询时,如预期得到表扫描(Table Scan):

SELECT * FROM [dbo].[MyTableWithoutPk] where [category_id] = 100

对MyTableWithPk执行相同查询时,由于category_id无索引,我预期仍为表扫描,但实际得到的是聚集索引扫描(Clustered Index Scan)!

SELECT * FROM [dbo].[MyTableWithPk] where [category_id] = 100

我忽略了什么?我查阅过《Table Scan and Index Scan in SQL》资料,其中提到:

如果category_id上没有索引,那么会执行表扫描

核心原因

这两个术语本质是同一操作的不同表述,区别只在于表的存储结构:

  • 对于无聚集索引的堆表(比如MyTableWithoutPk),数据库引擎会遍历整个堆结构来查找符合条件的数据,这个操作被称为表扫描。
  • 对于有聚集索引的表(比如MyTableWithPk),整个表的实际数据就存储在聚集索引的叶子节点中——换句话说,聚集索引就是表本身。当引擎需要遍历所有数据时,它实际上是在遍历聚集索引的叶子节点,因此这个操作被称为聚集索引扫描。

你看到的资料是笼统的表述,它把“遍历全表数据”这个行为统一称为“表扫描”,但SQL Server会根据表的存储类型(堆/聚集索引组织表)给出更精确的操作名称。

无论是表扫描还是聚集索引扫描,本质都是遍历所有数据行来筛选符合category_id=100的记录,性能上没有本质差异——只有给category_id创建非聚集索引,才能避免全量遍历的操作。

内容的提问来源于stack exchange,提问作者Julian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:12:32