非聚集索引使用密钥进入聚簇索引而不是地址?

时间:2013-05-24 08:33:45

标签: database sql-server-2008-r2 indexing clustered-index non-clustered-index

documentation for SQL server 2008 R2中声明:

  

宽键是多列或多个大型列的组合。来自聚簇索引的键值被所有非聚簇索引用作查找键。在同一个表上定义的任何非聚簇索引都将显着更大,因为非聚簇索引条目包含聚类键以及为该非聚簇索引定义的键列。

这是否意味着,当使用非聚集索引进行搜索时,聚集的indes也是搜索?我原本以为非聚集索引直接包含页面(块)的地址和它引用的行。从上面的文本看来,它只包含来自非聚集索引的密钥而不是地址。

有人可以解释一下吗?

1 个答案:

答案 0 :(得分:3)

是的,这正是发生的事情:

  • SQL Server在非聚集索引中搜索您的搜索值
  • 如果找到匹配项,则在该索引条目中还有群集密钥(构成聚簇索引的一列或多列)
  • 使用该群集密钥,现在执行密钥查找(通常也称为书签查找) - 搜索聚集索引以获取该值
  • 找到项目时,聚集索引导航结构的叶级别的整个数据记录存在并可以返回

SQL Server这样做,因为使用物理地址真的很糟糕:

  • 如果发生页面拆分,则会更新移动到新页面的所有条目
  • 对于所有这些条目,所有非聚集索引也必须更新

这对性能来说真的很糟糕。

这是为什么在SELECT中使用有限的列列表(而不是始终SELECT *)并且甚至可能在非聚簇索引中包含一些额外的列(为了使其成为有益)的原因之一覆盖索引)。这样,您就可以避免不必要且昂贵的书签查找。

因为聚类键包含在每个非聚簇索引中,所以非常重要的是这是一个和窄键 - 最好是INT IDENTITY或类似的东西 - 而不是庞大的结构;集群密钥是SQL Server中复制最多的数据结构,应该尽可能小。

这些书签查找相对昂贵的事实也是为什么查询优化器可能会在您选择更多行时选择索引扫描的原因之一 - 当时,只扫描聚簇索引可能是比做很多关键查找便宜。