gpt4 book ai didi

sql-server - 使用 GUID 作为主键的最佳实践是什么,特别是在性能方面?

转载 作者:行者123 更新时间:2023-12-01 16:19:43 25 4
gpt4 key购买 nike

我有一个应用程序,它在几乎所有表中都使用 GUID 作为主键,我读到使用 GUID 作为主键时存在性能问题。老实说,我没有看到任何问题,但我即将开始一个新的应用程序,我仍然想使用 GUID 作为主键,但我正在考虑使用复合主键(GUID 和另一个字段.)

我使用 GUID 是因为当您拥有不同的环境(例如“生产”、“测试”和“开发”数据库)以及数据库之间的迁移数据时,它们很好且易于管理。

我将使用 Entity Framework 4.3,我想在应用程序代码中分配 Guid,然后再将其插入数据库。 (即我不想让 SQL 生成 Guid)。

创建基于 GUID 的主键的最佳实践是什么,以避免与此方法相关的假设性能下降?

最佳答案

GUID 似乎是您的主键的自然选择 - 如果您真的必须这样做,您可能会争辩说将它用于表的 PRIMARY KEY。我强烈推荐的内容 不做使用 GUID 列作为 聚类 key ,默认情况下 SQL Server 会这样做,除非您明确告诉它不要这样做。
你真的需要把两个问题分开:

  • 主键 是一个逻辑结构 - 唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的 - 一个 INT , GUID , 一个字符串 - 选择最适合您的场景的内容。
  • 聚类 key (定义表上“聚集索引”的一列或多列)——这是一个与物理存储相关的东西,在这里,一个小的、稳定的、不断增加的数据类型是你最好的选择——INTBIGINT作为您的默认选项。

  • 默认情况下,SQL Server 表上的主键也用作集群键 - 但不必如此!当将以前的基于 GUID 的主键/集群键分解为两个单独的键时,我个人已经看到了巨大的性能提升 - GUID 上的主(逻辑)键和单独的 INT IDENTITY(1,1) 上的集群(排序)键柱子。
    Kimberly Tripp - 索引女王 - 和其他人已经说过很多次了 - GUID由于集群键不是最优的,由于其随机性,它会导致大量的页面和索引碎片,并且通常会导致性能不佳。
    是的,我知道 - 有 newsequentialid()在 SQL Server 2005 及更高版本中 - 但即使这样也不是真正和完全顺序的,因此也遇到与 GUID 相同的问题。 - 只是不那么突出。
    然后还有另一个需要考虑的问题:表上的聚集键也将添加到表上每个非聚集索引的每个条目中 - 因此您确实希望确保它尽可能小。通常,一个 INT 2+ 十亿行应该足以满足绝大多数表 - 与 GUID 相比作为集群键,您可以为自己节省数百兆字节的磁盘和服务器内存存储空间。
    快速计算 - 使用 INT对比 GUID作为主键和集群键:
  • 具有 1'000'000 行的基表(3.8 MB 与 15.26 MB)
  • 6 个非聚集索引(22.89 MB 与 91.55 MB)

  • 总计:25 MB 与 106 MB - 那只是在一张 table 上!
    还有一些值得深思的东西——金伯利·特里普 (Kimberly Tripp) 的优秀作品——阅读它,再读一遍,消化它!这是 SQL Server 索引的福音,真的。
  • GUIDs as PRIMARY KEY and/or clustered key
  • The clustered index debate continues
  • Ever-increasing clustering key - the Clustered Index Debate..........again!
  • Disk space is cheap - that's not the point!

  • PS:当然,如果你只处理几百或几千行——这些论点中的大多数不会对你产生太大影响。但是:如果您进入数万或数十万行,或者您开始​​数以百万计 - 然后 这些要点变得非常关键,非常重要,需要理解。
    更新:如果您想拥有您的 PKGUID列作为主键(但不是集群键),另一列 MYINT ( INT IDENTITY ) 作为你的集群键 - 使用这个:
    CREATE TABLE dbo.MyTable
    (PKGUID UNIQUEIDENTIFIER NOT NULL,
    MyINT INT IDENTITY(1,1) NOT NULL,
    .... add more columns as needed ...... )

    ALTER TABLE dbo.MyTable
    ADD CONSTRAINT PK_MyTable
    PRIMARY KEY NONCLUSTERED (PKGUID)

    CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
    基本上:你只需要 明确告诉 PRIMARY KEY约束它是 NONCLUSTERED (否则默认情况下它会创建为聚集索引) - 然后创建第二个索引,定义为 CLUSTERED这将起作用 - 如果您有一个需要“重新设计”以提高性能的现有系统,这是一个有效的选择。对于新系统,如果您从头开始,并且您不在复制场景中,那么我总是选择 ID INT IDENTITY(1,1)作为我的集群主键 - 比其他任何东西都更有效率!

    关于sql-server - 使用 GUID 作为主键的最佳实践是什么,特别是在性能方面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11938044/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com