然而,以聚集索引键作为非聚集索引的书签好要聚集索引键满足如下标准:

  索引应该具有性。每一个索引条目书签都应该使得书签可以通过聚集索引的键值的确认表中的一行,如果你创建的聚集索引键值不,SQL Server将会为有重复键值的每一行自动加上一个叫uniquifier的东西使得每一行。这个uniquifier对客户端是透明的。对于是否可以允许聚集索引键重复,你需要考虑以下两点:

  ● 生成uniquifier增加SQL Server插入操作的额外负担,在插入时SQL Server还需要判断插入的值在表中是否,如果不生成uniquifier值再进行插入。

  ● uniquifier本身对业务数据来说是没有意义的,但是这个uniquifier本身不仅仅需要占用聚集索引键的空间,还同时占用非聚集索引书签的空间。

  索引键应该短。索引键所占的字节数应该短.因为这个键还会占用非聚集索引书签的空间。比如Contact表中以Last name / first name / middle name / street组合作为索引键看上去不错,但如果表中存在多个非聚集索引的话情况有些微妙了。n个非聚集索引使得Last name / first name / middle name / street这些字段被存储在n+1个位置。

  索引键好不要变动。也是索引键的值好不要变动。对于聚集索引键的修改会使得基于这个聚集索引的所有非聚集索引同样进行修改。所以对于聚集索引的一次update会造成n个非聚集索引书签的update+1个聚集索引键值本身的update。

  AdventureWorks的设计团队在设计SalesOrderDetail表的聚集索引时是完全遵循上面的建议。它们选择SalesOrderID / SalesOrderDetailID作为聚集索引键完全满足了窄,短和的要求。将SalesOrderID作为索引键左边的一列,尽管SalesOrderDetailID是的,这两列组合在一起进行聚集。以SalesOrderID / SalesOrderDetailID作为主键和聚集索引键,不再需要单独建立SalesOrderDetailID的非聚集索引了。

  现在我们创建和列表6.1所示的非聚集索引一样的索引。的不同是现在这个版本是基于聚集索引而不是堆的。非聚集索引的部分数据如下:

我们现在有了两个版本的非聚集索引,分别是创建在堆上的非聚集索引和创建在聚集索引上的非聚集索引,的不同是它们的书签值。

  哪种更好

  上面两种聚集索引是不是一种要比另一种更好呢?或许吧,但是也要看具体情况。基于RID的书签允许快速的找到底层表中行所在的物理位置,而基于聚集索引的书签找到底层表的行慢多了,但这个书签还可以作为包含列使用,书签列同时也常常会被当作外键。

  所以对于上面哪种非聚集索引更好的真正答案是”都不是”。当在表上建立索引时,重要的选择只是使用哪些列作为索引键。一旦你确定了聚集索引列(基于文中所示的三点建议),剩下的非聚集索引所带来的影响交给SQL Server来处理吧。

  小结

  非聚集索引包含了索引键列,包含列和书签。书签的值根据所在表是堆还是聚集索引既可以是RID也可以是聚集索引键。对于表上聚集索引的好选择要基于文中所给的三点指南。