GUID性能

0 entity-framework sql-server-2012

我们正在开发一个非常大的 OLTP 数据库(SQL Server 2012)并考虑使用 GUID 作为主键(我记住不要使其成为集群),但是,我们不确定特别是性能的后果。我们首先使用 EF 代码。

有人可以帮我们决定吗?请包含文章链接。谢谢

mar*_*c_s 5

GUIDs 似乎是主键的自然选择 - 如果您确实必须这样做,您可能会争论将其用作表的主键。我强烈建议不要使用GUID列作为集群键,SQL Server 默认情况下会这样做,除非您明确告诉它不要这样做。

您确实需要分开两个问题:

  1. 是一个逻辑构造 - 唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,实际上 - 一个INT、一个GUID、一个字符串 - 选择对您的场景最有意义的。

  2. 聚集(定义表上聚集索引的一列或多列) - 这是与物理存储相关的事物,在这里,小型、稳定、不断增加的数据类型是您的最佳选择 -INT或者BIGINT作为您的默认选项。

默认情况下,SQL Server 表上的主键也用作聚簇键 - 但不必如此!我个人看到,将以前基于 GUID 的主键/聚集键分解为两个单独的键 - GUID 上的主(逻辑)键和单独列上的聚集(排序)键时,性能得到了巨大的提升INT IDENTITY(1,1)

正如索引女王Kimberly Tripp和其他人多次指出的那样,将 GUID 作为集群键并不是最佳选择,因为由于其随机性,它将导致大量页面和索引碎片,并且通常会导致性能不佳。

是的,我知道 - SQL Server 2005 及更高版本中存在newsequentialid()- 但即使这样也不是真正且完全顺序的,因此也遇到与 GUID 相同的问题 - 只是稍微不那么突出。

然后还有另一个问题需要考虑:表上的聚集键也将添加到表上每个非聚集索引的每个条目中 - 因此您确实希望确保它尽可能小。通常,具有 2+ 十亿行的 INT 对于绝大多数表来说应该足够了 - 与作为集群键的 GUID 相比,您可以在磁盘和服务器内存中节省数百兆字节的存储空间。

快速计算 - 使用INT与 GUID 作为主键和聚类键:

  • 具有 1'000'000 行的基表(3.8 MB 与 15.26 MB)
  • 6 个非聚集索引(22.89 MB 与 91.55 MB)

总计:25 MB 与 106 MB - 而且这只是在一个表上!

还有一些值得深思的东西 - Kimberly Tripp 写的很棒的东西 - 读它,再读它,消化它!这确实是 SQL Server 索引的福音。