sql >> Databáze >  >> RDS >> Sqlserver

Jaké jsou osvědčené postupy pro použití GUID jako primárního klíče, konkrétně pokud jde o výkon?

GUID se může zdát jako přirozená volba pro váš primární klíč – a pokud opravdu musíte, pravděpodobně byste mohli argumentovat, že je použijete pro PRIMÁRNÍ KLÍČ tabulky. Co bych důrazně doporučil nedělat je použít sloupec GUID jako klíč clusteru , což SQL Server ve výchozím nastavení dělá, pokud mu výslovně neřeknete, že to tak není.

Opravdu potřebujete oddělit dva problémy:

  1. primární klíč je logická konstrukce – jeden z kandidátských klíčů, který jednoznačně a spolehlivě identifikuje každý řádek ve vaší tabulce. Může to být opravdu cokoliv - INT , GUID , řetězec – vyberte, co má pro váš scénář největší smysl.

  2. klastrovací klíč (sloupec nebo sloupce, které definují „shlukovaný index“ v tabulce) – toto je fyzický věc související s úložištěm a tady je nejlepší volbou malý, stabilní a stále se zvyšující datový typ - INT nebo BIGINT jako výchozí možnost.

Ve výchozím nastavení se primární klíč v tabulce serveru SQL také používá jako klíč clusteru - ale nemusí to tak být! Osobně jsem zaznamenal masivní nárůst výkonu při rozdělení předchozího primárního / klastrovaného klíče založeného na GUID na dva samostatné klíče – primární (logický) klíč v GUID a klastrovací (objednací) klíč na samostatném INT IDENTITY(1,1) sloupec.

Jak Kimberly Tripp - královna indexování - a další mnohokrát prohlásili - GUID protože shlukovací klíč není optimální, protože kvůli jeho náhodnosti povede k masivní fragmentaci stránek a indexů a obecně špatnému výkonu.

Ano, já vím – existuje newsequentialid() v SQL Server 2005 a novějších – ale ani ten není skutečně a plně sekvenční, a proto také trpí stejnými problémy jako GUID - jen trochu méně nápadně.

Pak je tu další problém, který je třeba zvážit:shlukovací klíč v tabulce bude přidán také ke každé položce na každém neklastrovaném indexu ve vaší tabulce – opravdu se chcete ujistit, že je co nejmenší. Obvykle INT s více než 2 miliardami řádků by mělo stačit pro velkou většinu tabulek – a ve srovnání s GUID jako klastrovací klíč si můžete ušetřit stovky megabajtů úložiště na disku a v paměti serveru.

Rychlý výpočet - pomocí INT vs. GUID jako primární a klastrovací klíč:

  • Základní tabulka s 1 000 000 řádky (3,8 MB vs. 15,26 MB)
  • 6 neklastrovaných indexů (22,89 MB vs. 91,55 MB)

CELKEM:25 MB vs. 106 MB - a to jen na jednom stole!

Ještě něco k zamyšlení – vynikající věci od Kimberly Tripp – přečtěte si to, přečtěte si to znovu, strávte to! Je to skutečně evangelium indexování SQL Serveru.

  • GUID jako PRIMÁRNÍ KLÍČ a/nebo seskupený klíč
  • Debata o klastrovém indexu pokračuje
  • Stále rostoucí klíč shlukování – debata o seskupených indexech..........opět!
  • Místo na disku je levné – to není pointa!

PS:Samozřejmě, pokud máte co do činění s několika stovkami nebo tisíci řádky - většina z těchto argumentů na vás ve skutečnosti nebude mít velký dopad. Nicméně:pokud se dostanete do desítek či stovek tisíc řádků nebo začnete počítat v milionech – pak tyto body se stávají velmi zásadními a je velmi důležité jim porozumět.

Aktualizace: pokud chcete mít svůj PKGUID sloupec jako váš primární klíč (ale ne váš shlukovací klíč) a další sloupec MYINT (INT IDENTITY ) jako váš shlukovací klíč – použijte toto:

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)

V podstatě:stačí to výslovně sdělte PRIMARY KEY omezení, že je NONCLUSTERED (jinak je ve výchozím nastavení vytvořen jako váš seskupený index) - a poté vytvoříte druhý index, který je definován jako CLUSTERED

To bude fungovat - a je to platná možnost, pokud máte stávající systém, který je třeba "překonstruovat" pro výkon. Pro nový systém, pokud začínáte od nuly a nejste ve scénáři replikace, pak bych vždy vybral ID INT IDENTITY(1,1) jako můj seskupený primární klíč – mnohem efektivnější než cokoli jiného!



  1. Typ přetypování řetězce na celé číslo

  2. Vypočítejte časový rozdíl mezi dvěma řádky

  3. Vložení připraveného příkazu do databáze - PSQL

  4. Jak propojit databázi Accessu s SQL Serverem v Accessu 2016