簡體   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