繁体   English   中英

SQL Guid主键加入性能

[英]SQL Guid Primary Key Join Performance

我目前正在使用GUID作为NONCLUSTERED PRIMARY KEYINT IDENTITY列。

GUID必须允许脱机创建数据和同步 - 这是整个数据库的填充方式。

我知道将GUID用作聚簇主键的含义,因此是整数聚簇索引,但使用GUID作为主键,因此其他表上的外键具有显着的性能影响?

是否有更好的选择使用整数主/外键,并使用GUID作为客户端ID,每个表上都有一个UNIQUE INDEX - 我担心的是,实体框架需要加载导航属性才能获得相关实体的GUID,而无需对现有代码进行重大更改。

有问题的数据库/硬件是SQL Azure。

您还可以针对唯一键约束创建外键,然后为您提供ID身份的外键选项,作为Guid的替代。

Create Table SomeTable
(
    UUID UNIQUEIDENTIFIER NOT NULL,
    ID INT IDENTITY(1,1) NOT NULL,

    CONSTRAINT PK PRIMARY KEY NONCLUSTERED (UUID),
    CONSTRAINT UQ UNIQUE (ID)
)
GO

Create Table AnotherTable
(
    SomeTableID INT,

    FOREIGN KEY (SomeTableID) REFERENCES SomeTable(ID)
)
GO

编辑

假设您的集中式数据库是Mart,并且只从源数据库中完成批量ETL,如果您将ETL直接发送到中央数据库(即不通过Entity Framework ),假设所有表都具有UUID FK之后在分布式数据库中,您需要在ETL期间映射INT UKCs或在导入后修复它们(这需要在INT FK上执行临时的NOCHECK约束步骤)。

加载ETL并映射INT键后,我建议您忽略/删除ORM模型中的UUID - 您需要在INT键上重新生成EF导航。

如果直接更新中央数据库或执行连续的ETL并且使用EF作为ETL本身,则需要不同的解决方案。 在这种情况下,将PK GUID保留为RI的FK,完全删除INT FK,并选择其他合适的列进行聚类(最小化页面读取)可能会减少总I / O.

GUID具有重要意义,是的。 您的索引是非聚簇的,但索引本身将快速分段,外键上的索引也是如此。 大小也是一个问题:16字节而不是4字节整数。

您可以使用NEWSEQUENTIALID()函数作为列的默认值,以减少随机性并减少碎片。

但是,是的,我会说使用整数作为主键和参考将是最好的解决方案。

一般来说,最好使用INT作为主键/外键字段,无论这些字段是否是聚簇索引中的前导字段。 该问题与JOIN性能有关,即使您使用UNIQUEINDENTIFIER作为NonClustered,或者即使您使用NEWSEQUENTIALID()来减少碎片,随着表变大,它也会更加可扩展到INT字段之间的JOIN。 (请注意,我并不是说PK / FK字段应该始终为INT,因为有时候使用完全有效的自然键)。

在您的情况下,考虑到实体框架的关注并在应用程序而不是数据库中生成GUID,请使用您的备用建议使用INT作为PK / FK字段, 不要在所有表中使用UNIQUEIDENTIFIER,只放它在主用户/客户信息表中。 我认为您应该能够基于GUID一次性查找客户INT标识符,缓存该值,然后对所有剩余操作使用INT值。 是的,确保GUID字段上有一个UNIQUE,NONCLUSTERED索引。

尽管如此,如果你的表永远不会(我的意思是从不相反,只是在前两年),每个超过可能超过100,000行,那么使用UNIQUEIDENTIFIER就不那么值得关注,因为少量的行通常表现良好(给予适度适当的硬件,不会因其他进程负担过重或内存不足而导致。 显然,由于使用UNIQUEIDENTIFIER而导致JOIN性能下降的程度将在很大程度上取决于系统的具体情况:硬件以及查询的类型,查询的编写方式以及系统的负载程度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM