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

usr*_*usr 11 sql-server database-design primary-key clustered-index sql-server-2008

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

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

create table Customers(ID int,...)create table Orders(ID int,CustomerID int)

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

mar*_*c_s 13

根据索引女王 - 金佰利特里普 - 她在聚集索引中寻找的主要是:

  • 独特
  • 狭窄
  • 静态的

如果您还可以保证:

  • 不断增加的模式

然后你非常接近拥有理想的聚类键!

查看她在这里的整个博客文章,以及另一个非常有趣的关于集群对表操作的关键影响:集群索引辩论继续.

任何像INT(尤其是INT IDENTITY)或者可能是INT和DATETIME的东西都是理想的候选者.由于其他原因,GUID根本不是好的候选者 - 所以你可能有一个GUID作为你的PK,但不要将你的表聚集在它上面 - 它将被分割得无法识别并且性能会受到影响.


Qua*_*noi 6

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

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

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

如果您创建CLUSTERED索引Orders.CustomerID,将发生以下事情:

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

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

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

  4. 像这样的查询:

    SELECT  *
    FROM    Orders
    WHERE   ID = 1234567
    
    Run Code Online (Sandbox Code Playgroud)

    将不得不进行外部操作,Clustered Seek因为并非所有列都存储在索引中ID.要检索所有列,记录应首先位于群集表中.

此附加操作需要IndexDepth尽可能多的页面读取Clustered Seek,即IndexDepth表格O(log(n))中记录总数的简单描述.