【问题标题】:GUID Performance [closed]GUID 性能 [关闭]
【发布时间】:2013-02-21 14:51:25
【问题描述】:

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

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

【问题讨论】:

    标签: entity-framework sql-server-2012


    【解决方案1】:

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

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

    1. 主键 是一种逻辑结构 - 候选键之一,可唯一且可靠地标识表中的每一行。这可以是任何东西,真的——INTGUID、字符串——选择对你的场景最有意义的东西。

    2. clustering key(定义表上clustered index的一列或多列) - 这是一个物理存储- 相关的东西,在这里,一个小的、稳定的、不断增长的数据类型是你最好的选择 - INTBIGINT 作为你的默认选项。

    默认情况下,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 vs. 106 MB - 这只是在一张桌子上!

    更多值得深思的东西 - Kimberly Tripp 的优秀作品 - 阅读,再阅读,消化!这是 SQL Server 索引的福音,真的。

    【讨论】:

    • 非常感谢 marc_s,虽然我不打算对 GUID 列进行聚类,但我发现这些文章信息量很大。我仍然需要做更多的测试才能做出决定
    猜你喜欢
    • 2010-09-15
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    相关资源
    最近更新 更多