通常,通过设置主键在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创建它。这是最好的选择吗?
答案 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
索引,则会发生以下情况:
CustomerID
不是唯一的。为确保唯一性,我们会在每条记录中添加一个称为32-bit
的特殊隐藏uniquifier
列。
表格中的记录将根据这对列(CustomerID, uniquifier)
进行存储。
将创建Order.ID
上的辅助索引,其中(CustomerID, uniquifier)
作为记录指针。
这样的查询:
SELECT *
FROM Orders
WHERE ID = 1234567
必须执行外部操作Clustered Seek
,因为并非所有列都存储在ID
的索引中。要检索所有列,记录应首先位于聚簇表中。
此附加操作需要IndexDepth
页面读取数量与简单Clustered Seek
一样多,表格中记录总数的IndexDepth
beign O(log(n))
。
答案 2 :(得分:1)
如果您担心群集,通常是为了帮助改进数据检索。在您的示例中,您可能希望立即获得给定客户的所有记录。对customerID进行聚类会将这些行保留在同一物理页面上,而不是分散在文件中的多个页面中。
ROT:群集在你想要展示的集合上。采购订单中的行项目是典型示例。