10

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

那么我们该如何选择聚簇索引呢?让我们下面的例子:

创建Customers表(ID INT,...) 创建表Orders(ID INT,客户ID INT)

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

+0

可能的重复[SQL Server - 何时使用群集与非群集索引?](https://stackoverflow.com/questions/18304376/sql-server-when-to-use-clustered-vs-non-集群索引) –

回答

11

根据女王索引点 - 金佰利特里普 - 她在一个聚集索引查找主要是:

  • 独特
  • 静态

如果您还可以保证:

  • 不断增加的模式

那么你就相当接近你的理想聚类关键!

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

任何类似于INT(特别是INT IDENTITY)或可能是INT和DATETIME都是理想的选择。由于其他原因,GUID根本就不是很好的候选人 - 所以你可能有一个GUID作为你的PK,但是不要将你的表集成在它上面 - 它将被分割得无法识别,性能将受到影响。

+0

这些博客帖子是否仍然与更新版本的SQL Server相关,或者最近在SQL Server 2008中进行了性能调整,并且后来以某种方式更改了最佳做法? –

+0

@AdrianGrigore:只要你使用“普通”表(例如not datawarehouse/columnstore stuff),一切仍然有效 –

+0

非常感谢! :) –

1

如果您关心集群,通常会帮助改进数据检索。在你的例子中,你可能会想要一次给定客户的所有记录。 customerID上的集群会将这些行保留在同一物理页面上,而不是分散在文件中的多个页面上。

ROT:您想显示集合的集群。采购订单中的行项目就是一个典型例子。

+0

订单中的订单项可能是集群的好主意,但如果典型订单上只有2个或3个(或12个)订单项,则不适用。除非您集群的行开始进入数十或数百个,否则最好让SQL Server执行书签查找。我有一个系统,业务需求必须找到特定出纳员轮班期间发生的所有“行项目”(以查看它们是否平衡)。如果使用** Shift **,然后在** Shift **上进行聚类,则用“id”反正规化“行项目”是一个巨大的速度提升。 –

6

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

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

就你而言,Orders.ID很可能会参与搜索和引用,所以它是成为聚类表达式的最佳人选。

如果您创建Orders.CustomerIDCLUSTERED指数,下面的事情会发生:

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

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

  3. 将创建Order.ID的二级索引,并使用(CustomerID, uniquifier)作为记录指针。

  4. 查询是这样的:

    SELECT * 
    FROM Orders 
    WHERE ID = 1234567 
    

    将不得不做外部操作,Clustered Seek,因为不是所有的列存储在索引上ID。要检索所有列,记录应首先位于聚簇表中。

这种额外的操作需要IndexDepth尽可能多的网页读作一个简单的Clustered Seek,在你的表中的记录总数的IndexDepth beign O(log(n))

相关问题