据我所知,堆表是没有聚簇索引并且没有物理顺序的表。我有一个具有12万行的堆表“扫描”,并且正在使用以下选择:
SELECT id FROM scan
如果为“ id”列创建非聚集索引,则将获得 223次物理读取 。如果删除非聚集索引并更改表以使“ id”成为主键(以及聚集索引),则将获得 515次物理读取 。
如果聚集索引表如下图所示:
为什么聚簇索引扫描的工作方式类似于表扫描?(或者在检索所有行的情况下更糟)。为什么不使用块较少且已经具有所需ID的“聚集索引表”?
SQL Server索引是b树。非聚集索引仅包含索引列,而b树的叶子节点是指向适当数据页面的指针。聚簇索引是不同的:它的叶节点是数据页本身,而聚簇索引的b树成为表本身的后备存储。该表的堆不再存在。
您的非聚集索引包含单个(可能是整数)列。首先是一个小的紧凑索引。您的查询select id from scan具有 覆盖索引 :仅通过检查索引即可满足查询的要求。但是,如果查询中的列不包含在索引中,则假设优化器选择使用非聚集索引,则将需要进行额外的查找以从集群索引或堆中获取所需的数据页。
select id from scan