1

为简单起见,假设我在 Sql Server 中有一个表“Car”。它有 2 列。“Id”是唯一标识符/Guid,是主键。“名称”是一个 nvarchar/字符串。该数据库将用于轻度使用的应用程序,该应用程序的峰值可能为 10 个并发用户。“汽车”可能有数千行。它将被定期查询、插入和更新。

我知道在 Guid 列上有一个聚集索引通常是不好的,所以我的计划是将表保留为堆并且没有聚集索引。我会在 Id 上有一个非聚集索引。

在这个非常简单的场景中,我有什么理由会后悔没有聚集索引?如果你说是,请解释你的答案背后的原因。我看过人们说“我添加一个 int 列只是为了添加一个聚集索引”的帖子。如果您不打算查询 int 列,我无法弄清楚为什么有人会这样做,它会增加什么价值?

同样对于这个例子,请假设 newsequentialid() 不是一个选项。我首先使用实体​​框架模型,使用起来很痛苦(除非有人能指出一种我错过的简单方法)。还假设 Guid PK 是一项要求(它是现有系统)。

4

1 回答 1

8

使用 GUID 作为主键,高百分比的插入将导致索引中的页面拆分。糟糕的页面拆分,也会导致碎片化。您可以使用更宽松的填充因子来推迟其中的一些,但这仍然只是一种推迟,并迫使您同时使用更多空间。

当一IDENTITY列被聚集时,假设您不重新设置种子或使用SET IDENTITY_INSERT ON,它会强制将新插入到表的末尾,从而消除这些页面拆分。(可以说这会导致一个不同的问题——“插入热点”——但对于 1000 行,我认为这不会是一个主要问题。)

如果表上没有聚集索引,您可能会面临涉及转发行的性能问题

如果您与 GUID 相关联,则应考虑NEWSEQUENTIALID()避免这些问题,并在此基础上进行集群。如果您不依赖于 GUID,则应考虑使用IDENTITY而不是GUID,并在其上进行聚类。我认为没有聚集索引没有任何好处,除非您避免在基表上进行页面拆分。

于 2013-08-28T21:09:03.147 回答