当前位置: 首页 > 知识库问答 >
问题:

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

单耘豪
2023-03-14

我有一个在几乎所有表中使用GUID作为主键的应用程序,并且我读到使用GUID作为主键时存在性能问题。老实说,我没有看到任何问题,但我即将启动一个新的应用程序,我仍然希望使用GUID作为主键,但我想使用一个复合主键(GUID和另一个字段)

我之所以使用GUID,是因为当您有不同的环境(如“Production”、“Test”和“Dev”数据库)时,以及在数据库之间迁移数据时,它们很好并且易于管理。

我将使用Entity Framework4.3,我想在应用html" target="_blank">程序代码中分配Guid,然后再将其插入数据库。(即我不想让SQL生成Guid)。

创建基于GUID的主键的最佳实践是什么,以避免与此方法相关联的预期性能打击?

共有1个答案

晏树
2023-03-14

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

你真的需要把两个问题分开:

>

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

    正如索引女王Kimberly Tripp和其他人多次指出的那样,GUID作为聚类键并不是最佳的,因为由于它的随机性,它会导致大量的页面和索引碎片,并导致总体上的糟糕性能。

    是的,我知道--在SQL Server2005及更高版本中有newSequentialID()-但即使它也不是真正的完全顺序的,因此也会遇到与GUID相同的问题--只是稍微不那么突出而已。

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

    快速计算-使用intguid作为主键和群集键:

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

    总数:25 MB对106 MB--这只是在一张桌子上!

      null
    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)
    

    这将起作用--如果您有一个现有的系统需要“重新设计”以提高性能,这是一个有效的选择。对于一个新系统,如果您从头开始,并且不在复制场景中,那么我总是选择id INT IDENTITY(1,1)作为我的集群主键--比其他任何东西都要高效得多!

  •  类似资料:
    • 原始关闭原因未解决 我有一个几乎在所有表中使用GUID作为主键的应用程序,我已经读到使用GUID作为主键时存在性能问题。老实说,我没有看到任何问题,但我即将开始一个新的应用程序,我仍然想使用GUID作为主键,但我正在考虑使用复合主键(GUID,也许还有另一个字段)。 我之所以使用GUID,是因为当您有不同的环境(例如“生产”、“测试”和“开发”数据库)时,它们很好,而且易于管理,还可以在数据库之间

    • 问题内容: 我刚开始学习Go,并通读现有代码以学习“其他人的做法”。在这种情况下,遍历使用go“工作区”,尤其是与项目依赖关系有关的地方。 在处理各种Go项目时,使用一个或多个Go工作区(即$ GOPATH的定义)的常见(或存在)最佳实践是什么?我应该期望有一个类似于我所有项目的中央代码存储库的Go工作区,还是在我处理这些项目时都明确将其分解并设置$ GOPATH(有点像python) virtu

    • 问题内容: 我在某处读到,使用如下所示的类实例不是一个好主意,因为它们可能会导致内存泄漏。有人可以告诉我这是否是有效的声明?还是他们用这种方式有问题吗? 问题答案: 是的,您必须要小心!例如,如果您的代码在Web容器中运行,并且习惯于热部署Web应用程序,则对单个类对象的保留引用可能会导致大量Permgen内存泄漏。 本文详细解释了该问题。简而言之,问题在于每个类都包含对其类加载器的引用,而每个类

    • 问题内容: 我将开始使用AngularJS进行客户端和Django进行服务器端项目。 使他们像最好的朋友一样工作的最佳实践是什么(静态文件,身份验证,部署等) 问题答案: 有多种方法可以从Django模板中为客户端模板提供支持,以实现有趣的优化。但是,鉴于Django和AngularJS的模板语言之间的相似之处,在这里几乎不值得付出任何努力。对于此类大多数项目,我会将AngularJS的静态服务与

    • 那么使用clientResponse()的最佳实践是什么?如果唯一的问题是应用程序不知道何时应该关闭连接,.exchange().block()会自动关闭连接吗?如果我应该使用.close()-我应该如何获得这个方法?也许我应该使用另一个版本的spring-webflux?或者也许还有另一种在Spring中检索响应主体和状态的最佳方法--WebFlux?

    • 问题内容: 我正在构建一个基于expressjs的应用程序,我想在其中记录所有事件。我可以找到温斯顿,这似乎很酷。无论如何,我正在寻找一种方法将其连接到我的expressjs应用程序。 我还想要在应用程序内部登录。我的要求不是那么简单,所以我想将所有内容记录在我的应用程序中(不仅是请求)。 我目前的情况: server.js (我想在此级别记录http请求) 路线/something.js con