主键是否应始终指定为聚簇索引

时间:2011-01-04 19:17:06

标签: sql sql-server clustered-index

我有一个SQLServer表来存储员工详细信息,列ID是GUID类型,而EmployeeNumber列是INT类型。大部分时间我都会在加入时选择EmployeeNumber并选择条件。

我的问题是,在ClusteredIndex为EmployeeNumber的情况下,将PrimaryKey分配给ID列是否合理?

6 个答案:

答案 0 :(得分:8)

理想的聚簇索引键是:

  1. 顺序
  2. 选择性(没有欺骗,每条记录都是唯一的)
  3. 精细
  4. 在查询中使用
  5. 一般来说,使用GUID作为聚簇索引键是一个非常糟糕的想法,因为它会在添加行时导致碎片化。

    编辑清晰度:

    PK和群集密钥确实是单独的概念。您的PK不需要是您的聚集索引键。

    实际应用中,根据我自己的经验,您的PK应该/将成为您的群集密钥,因为它符合上面列出的相同条件。

答案 1 :(得分:8)

是的,可以拥有非群集主键,并且可以拥有与主键完全无关的群集密钥。默认情况下,主键也可以成为聚簇索引键,但这不是必需的。

主键是一个逻辑概念:是数据模型中用于引用实体的键 聚集索引键是一个物理概念:是您希望将行存储在磁盘上的顺序。

当您需要比主键更窄的群集密钥时,选择不同的群集密钥会受到各种因素的驱动,例如密钥 width (因为群集密钥会在每个中复制/ em>非聚集索引。或支持频繁的范围扫描(在时间序列中很常见),当频繁使用date between '20100101' and '20100201'等查询({{1}上的聚簇索引键)访问数据时适当的。)

此主题已在此处讨论过,但请参阅What column should the clustered index be put on?

答案 2 :(得分:2)

首先,我必须说我对选择GUID作为此表的主键有疑虑。我认为EmployeeNumber可能是一个更好的选择,而且员工自然独特的东西会比这更好,例如SSN(或ATIN),雇主必须合法获得(至少在美国)。

除此之外,您永远不应该在GUID列上建立聚簇索引。聚集索引指定表中行的物理顺序。由于GUID值(理论上)是完全随机的,因此每个新行都将落在随机位置。这对性能非常不利。有一种叫做“顺序”的GUID,但我认为这有点像黑客。

答案 3 :(得分:0)

聚簇索引会导致数据以该顺序物理存储。因此,在测试连续行的范围时,聚簇索引可以提供很多帮助。

GUID是非常糟糕的聚集索引,因为他们的订单不是一个合理的订单模式。 Int Identity列不是更好,除非输入顺序有帮助(例如最近的雇用)

由于您可能不会寻找员工范围,因此可能无关紧要的是Clustered指数,除非您可以对您通常不感兴趣的员工进行细分(例如终止日期)

答案 4 :(得分:0)

由于EmployeeNumber是唯一的,我会把它变成PK。在SQL Server中,PK通常是聚集索引。

加入GUID真是太可怕了。 @JNK很好地回答了这个问题。

答案 5 :(得分:0)

在主键之外的其他内容上使用clustured index将提高SELECT查询的性能,这将利用此索引。

但是你会在UPDATE查询上失去性能,因为在大多数情况下,他们依靠主键来找到你想要更新的特定行。

CREATE查询也可能导致性能下降,因为当您在索引中间添加新行时,必须移动很多行(物理上)。在具有增量的主键上不会发生这种情况,因为最终总会添加新记录,并且不会移动任何其他行。

如果您不知道哪种操作需要最高性能,我建议将聚簇索引保留在主键上,并在常用搜索条件上使用非聚簇索引。