11

我有一个存储员工详细信息的 SQLServer 表,列 ID 是 GUID 类型,而列 EmployeeNumber 是 INT 类型。大多数时候,我会在进行连接和选择标准时处理 EmployeeNumber。

我的问题是,将 PrimaryKey 分配给 ID 列而 ClusteredIndex 分配给 EmployeeNumber 是否明智?

4

6 回答 6

11

是的,可以有一个非聚集的主键,也可以有一个与主键完全无关的聚集键。默认情况下,主键也成为聚集索引键,但这不是必需的。

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

选择不同的聚集键受多种因素的驱动,例如当您希望聚集键比主键更窄时的键宽度(因为聚集键会在每个非聚集索引中复制。或者支持频繁范围扫描(常见于时间序列),当数据经常被查询访问时date between '20100101' and '20100201'(一个聚集索引键date是合适的)。

之前已经在这里讨论过这个主题令人作呕,另请参阅聚簇索引应该放在哪一列?.

于 2011-01-04T19:44:13.573 回答
10

理想的聚集索引键是:

  1. 顺序的
  2. 选择性(没有欺骗,每条记录都是唯一的)
  3. 狭窄
  4. 用于查询

一般来说,使用 GUID 作为聚集索引键是一个非常糟糕的主意,因为它会在添加行时导致大量碎片。

编辑清晰:

PK 和 Clustered key 确实是不同的概念。您的 PK 不需要是您的聚集索引键。

根据我自己的经验,在实际应用中,与您的 PK 相同的字段应该/将是您的集群键,因为它符合上面列出的相同标准。

于 2011-01-04T19:29:58.127 回答
2

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

撇开这一点不谈,您永远不应该将聚集索引基于 GUID 列。聚集索引指定表中行的物理顺序。由于 GUID 值(理论上)是完全随机的,因此每个新行都将落在随机位置。这对性能非常不利。有一种叫做“顺序”GUID 的东西,但我认为这有点骇人听闻。

于 2011-01-04T19:28:44.233 回答
0

聚集索引使数据按该顺序物理存储。因此,在测试连续行的范围时,聚集索引有很大帮助。

GUID 是非常糟糕的聚集索引,因为它们的顺序不是一个合理的排序模式。除非输入顺序有帮助(例如最近的员工),否则 Int Identity 列并没有好多少

由于您可能不是在寻找员工范围,因此聚集索引可能并不重要,除非您可以分割您通常不感兴趣的员工块(例如终止日期)

于 2011-01-04T19:28:57.043 回答
0

由于 EmployeeNumber 是唯一的,因此我将其设为 PK。在 SQL Server 中,PK 通常是聚集索引。

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

于 2011-01-04T19:36:42.287 回答
0

在除主键之外的其他东西上使用聚集索引将提高 SELECT 查询的性能,这将利用此索引。

但是你会降低 UPDATE 查询的性能,因为在大多数情况下,它们依赖于主键来找到你想要更新的特定行。

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

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

于 2016-04-26T14:00:38.457 回答