it-swarm-eu.dev

Kdy by měl být primární klíč deklarován jako neslastovaný?

Při vytváření testovací databáze pro další otázku, kterou jsem položil dříve, jsem si vzpomněl, že primární klíč může být deklarován NONCLUSTERED

Kdy byste použili primární klíč NONCLUSTERED na rozdíl od primárního klíče CLUSTERED?

Díky předem

177
Stuart Blackler

Otázka není „kdy by měl být PK NC“, ale místo toho byste se měli ptát „jaký je správný klíč pro seskupený index“?

A odpověď opravdu záleží na jak dotazujete data. Seskupený index má výhodu oproti všem ostatním indexům: protože vždy zahrnuje všechny sloupce, vždy pokrývá. Proto dotazy, které mohou využít seskupený index, rozhodně nemusí používat vyhledávání k uspokojení některých promítaných sloupců a/nebo predikátů.

Další kousek skládačky je jak lze index použít? Existují tři typické vzory:

  • sondy, když je v indexu hledána jedna hodnota klíče
  • skenuje rozsah, když je načten rozsah klíčových hodnot
  • pořadí podle požadavků, když index může uspokojit objednávku bez nutnosti vyžadovat stop-and-go řazení

Pokud tedy analyzujete očekávané zatížení (dotazy) a zjistíte, že velký počet dotazů by používal určitý index, protože používají určitý vzorec přístupu, který těží z indexu, má smysl navrhnout tento index jako seskupený index.

Ještě dalším faktorem je to, že klastrovaný indexový klíč je vyhledávací klíč používaný všemi neklastrovanými indexy, a proto široký klastrovaný indexový index vytváří efekt zvlnění a rozšiřuje všechny nesloučené indexy a široké indexy více stránek, více I/O, více paměti, méně dobroty.

Dobrý seskupený index je stabilní, během životnosti entity se nemění, protože změna v hodnotách klíče seskupeného indexu znamená, že řádek musí být odstraněn a vložen zpět.

A dobrý seskupený index roste, aby nebyl náhodně (každá nově vložená hodnota klíče je větší než předchozí hodnota), aby nedošlo k rozštěpení a fragmentaci stránky (aniž by došlo k rozesílání s FILLFACTORs).

Takže nyní, když víme, co je dobrý seskupený indexový klíč, odpovídá primární klíč (což je logická vlastnost pro modelování dat) požadavkům? Pokud ano, pak by měl být PK seskupen. Pokud ne, pak by PK neměl být seskupen.

Chcete-li uvést příklad, zvažte tabulku faktů o prodeji. Každá položka má ID, které je primárním klíčem. Převážná většina dotazů však vyžaduje data mezi datem a jiným datem, proto nejlepším sdruženým indexovým klíčem by byl prodej datum, nikoli ID . Dalším příkladem odlišného seskupeného indexu od primárního klíče je klíč s velmi nízkou selektivitou, jako je „kategorie“ nebo „stav“, klíč s pouze několika málo odlišnými hodnotami. Mít klastrovaný indexový klíč s tímto klíčem s nízkou selektivitou jako klíč vlevo, např. (state, id), často dává smysl kvůli prověřování rozsahů, které vyhledávají všechny položky v určitém stavu.

Jedna poslední poznámka o možnosti nezeskupeného primárního klíče přes halda (tj. Neexistuje žádný seskupený index). Toto může být platný scénář, typický důvod je, když je výkon hromadné vložky kritický, protože haldy mají výrazně lepší propustnost hromadné vložky ve srovnání se seskupenými indexy.

194
Remus Rusanu

Základní důvod použití klastrovaných indexů je uveden na Wikipedia :

Clustering změní datový blok do určitého odlišného pořadí tak, aby odpovídalo indexu, což vede k tomu, že se řádková data uloží v pořadí. Proto lze v dané databázové tabulce vytvořit pouze jeden seskupený index. Seskupené indexy mohou výrazně zvýšit celkovou rychlost načítání, ale obvykle pouze , kde se k datům přistupuje postupně ve stejném nebo obrácené pořadí seskupeného indexu , nebo když je vybrán rozsah položek.

Řekněme, že mám tabulku lidí a tito lidé mají sloupec Země a jedinečný primární klíč. Je to demografická tabulka, takže to jsou jediné věci, na kterých mi záleží; jaká země a kolik jedinečných lidí je s touto zemí spojeno.

Je tedy pravděpodobné, že si VYBRAJEM KDE nebo OBJEDNÁVKU sloupec Země; seskupený index na primárním klíči mi nedělá nic dobrého, nepřistupuji k těmto datům pomocí PK, přistupuji k němu v tomto druhém sloupci. Protože mohu mít na stole pouze jeden seskupený index, deklarace mého PK jako Clustered by mi zabránila v použití Clustered Index on Country.

Kromě toho je zde dobrý článek o Clustered vs Nonclustered Indexes , ukáže se, že seskupené indexy způsobily problémy s výkonem vložení v SQL Server 6.5 (což alespoň snad není pro většinu z nás relevantní).

Pokud umístíte seskupený index do sloupce IDENTITY, všechny vaše vložení se stane na poslední stránce tabulky - a tato stránka je uzamčena po dobu trvání každé IDENTITY. Žádný velký problém ... pokud nemáte 5000 lidí, kteří všichni chtějí poslední stránku. Pak máte pro tuto stránku hodně sporu

U novějších verzí tomu tak není.

27
Ben Brocka

Pokud je váš primární klíč UNIQUEIDENTIFIER, ujistěte se, že je to NONCLUSTERED. Pokud je nastavíte jako seskupený, bude muset každá vložka provést spoustu míchání záznamů, aby vložila nový řádek na správnou pozici. Tím se zvýší výkon tanku.

17
Bryan Johns

Velmi běžný příklad:

  • Customer tabulka s CustomerID jako CLUSTERED PRIMARY KEY
  • Objednejte tabulku s OrderID (PK), CustomerID, OrderDate a některými dalšími sloupci
  • OrderPositions with OrderPositionID (PK), OrderId, ProductID, Amount, Price ...
  • musíte indexovat tabulky objednávek

Samozřejmě "záleží" je - téměř vždy - správná odpověď, ale většina aplikací (nikoli BI-Reports) bude fungovat na základě zákazníka (např. Přihlásíte se jako zákazník 278 na web a kliknete na "Moje objednávky" nebo referent uvede všechny objednávky pro zákazníka 4569 nebo vaše fakturační rutina sčítá všechny objednávky pro zákazníka 137).

V tomto případě by nemělo velký smysl seskupovat tabulku podle OrderID. Ano, budete mít dotazy jako SELECT ... WHERE OrderId = ?, Abyste uvedli podrobnosti o objednávce, ale obvykle by to bylo krátké a levné vyhledávání (3 čtení).

Na druhou stranu, pokud byste seskupili vaši tabulku Order podle CustomerID, nemuselo by se provádět vícenásobné vyhledávání klíčů při každém dotazu na tabulku pro CustomerId = ?.

CLUSTERED INDEX By měl být vždy UNIQUE, jinak by SQL Server přidal neviditelný (= nepoužitelný) INT sloupec UNIQUIFIER, aby zajistil jedinečnost - a bylo by mnohem rozumnější přidat reálná (použitelná) data, pak některá náhodná (v závislosti na pořadí vkládání) věci.

Protože zákazník (doufejme) zadá více než jednu objednávku, museli bychom přidat buď OrderID, nebo (pokud pro to obvykle řadíte), OrderDate (pokud se jedná o datetime - jinak zákazník by byl omezen na jednu objednávku denně) na CLUSTERED INDEX a skončil s:

CREATE UNIQUE CLUSTERED INDEX IX_Orders_UQ on Orders (CustomerID, OrderID)

Stejná pravidla platí pro tabulku OrderPositions. Většina dotazů obvykle uvádí všechny pozice pro konkrétní pořadí, takže byste měli vytvořit PK s OrderPositionID jako NONCLUSTERED a UNIQUE CLUSTERED INDEX Na OrderId, OrderPositionID.

BTW: Je správné, že tabulka Customer je seskupena podle svého PK (CustomerID, protože se jedná o tabulku nejvyšší úrovně) a bude - v typické aplikaci - většinou dotazována. jeho zákaznickým ID.

Čistě vyhledávací tabulky jako např. Genders nebo InvoiceTypes nebo PaymentType jsou dalším příkladem tabulek, které by měly být seskupeny jeho PK (protože se k nim obvykle připojíte na GenderId, InvoiceTypeId nebo PaymentTypeId).

8
Thomas Franz

Když je seskupený index považován za výhodnější pro celý systém než seskupený PK pomocí určité míry výkonu. V tabulce může být pouze jeden seskupený index.

Příkladem měření výkonu je doba jednoho dotazu (rychlost), integrace celkových časů dotazu do tabulky (efektivita) a potřeba přidat mnoho zahrnutých sloupců do a do velmi velkého neskupovaného indexu, aby se dosáhlo výkonu podobného seskupenému (velikost) ).

K tomu může dojít, když jsou data obecně získávána pomocí indexu, který není jedinečný, obsahuje nuly (není povoleno v PK), nebo byl PK přidán z sekundárního důvodu (jako je například replikace nebo identifikace záznamu auditu).

2
crokusek