如何在SQL Server中选择聚簇索引?

时间:2010-02-15 16:28:51

标签: sql-server database-design sql-server-2008 primary-key clustered-index

通常,通过设置主键在SQL Server Management Studio中创建聚簇索引,但是我最近关于PK< - >的问题。聚集索引(Meaning of Primary Key to Microsoft SQL Server 2008)表明没有必要将PK和聚集索引设置为相等。

那么我们应该如何选择聚簇索引呢?我们有以下示例:

创建表Customers(ID int,...) create table Orders(ID int,CustomerID int)

我们通常会在两个ID列上创建PK / CI,但我想为CustomerID中的Orders创建它。这是最好的选择吗?

3 个答案:

答案 0 :(得分:12)

根据索引女王 - Kimberly Tripp - 她在聚集索引中寻找的主要是:

  • 唯一
  • 精细
  • 静态

如果你还可以保证:

  • 不断增加的模式

然后你非常接近拥有理想的群集密钥!

查看她的整个blog post here,以及另一个非常有趣的关于对表操作的关键影响:The Clustered Index Debate Continues

任何类似INT(特别是INT IDENTITY)或可能是INT和DATETIME的东西都是理想的候选者。由于其他原因,GUID根本不是好的候选人 - 所以你可能有一个GUID作为你的PK,但是不要把你的桌子聚集在它上面 - 它会被分割得无法辨认,性能会受到影响。

答案 1 :(得分:6)

CLUSTERED索引的最佳候选者是您用来最常引用记录的关键。

通常,这是PRIMARY KEY,因为它是搜索和/或FOREIGN KEY关系中使用的内容。

在您的情况下,Orders.ID很可能会参与搜索和引用,因此它是成为聚类表达式的最佳候选者。

如果您在CLUSTERED上创建Orders.CustomerID索引,则会发生以下情况:

  1. CustomerID不是唯一的。为确保唯一性,我们会在每条记录中添加一个称为32-bit的特殊隐藏uniquifier列。

  2. 表格中的记录将根据这对列(CustomerID, uniquifier)进行存储。

  3. 将创建Order.ID上的辅助索引,其中(CustomerID, uniquifier)作为记录指针。

  4. 这样的查询:

    SELECT  *
    FROM    Orders
    WHERE   ID = 1234567
    

    必须执行外部操作Clustered Seek,因为并非所有列都存储在ID的索引中。要检索所有列,记录应首先位于聚簇表中。

  5. 此附加操作需要IndexDepth页面读取数量与简单Clustered Seek一样多,表格中记录总数的IndexDepth beign O(log(n))

答案 2 :(得分:1)

如果您担心群集,通常是为了帮助改进数据检索。在您的示例中,您可能希望立即获得给定客户的所有记录。对customerID进行聚类会将这些行保留在同一物理页面上,而不是分散在文件中的多个页面中。

ROT:群集在你想要展示的集合上。采购订单中的行项目是典型示例。