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

Vytvořte více než jeden neseskupený index ve stejném sloupci na serveru SQL Server

Slovíčka jsou poměrně logická a naučíte se je celkem rychle. :)

Laicky řečeno, SEEK znamená hledání přesných umístění záznamů, což je to, co SQL Server dělá, když je sloupec, ve kterém hledáte, indexován a váš filtr (podmínka WHERE) je dostatečně přesný.

SCAN znamená větší rozsah řádků, u kterých plánovač provádění dotazů odhaduje, že je rychlejší načíst celý rozsah než individuální hledání každé hodnoty.

A ano, můžete mít více indexů na stejném poli a někdy to může být velmi dobrý nápad. Pohrajte si s indexy a pomocí plánovače provádění dotazů určete, co se stane (zkratka v SSMS:Ctrl + M). Můžete dokonce spustit dvě verze stejného dotazu a plánovač provádění vám snadno ukáže, kolik zdrojů a času každá zabírá, takže optimalizace je docela snadná.

Ale abych je trochu rozšířil, řekněme, že máte takovou tabulku adres, která má více než 1 miliardu záznamů:

CREATE TABLE ADDRESS 
  (ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX
  , PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX
  , CITY VARCHAR(256)
  , MARKED_FOR_CHECKUP BIT
  , **+n^10 different other columns...**)

Nyní, pokud chcete najít všechny informace o adrese pro osobu 12345, je index na PERSON_ID perfektní. Vzhledem k tomu, že tabulka obsahuje spoustu dalších dat na stejném řádku, bylo by neefektivní a náročné na prostor vytvořit index bez klastrů, který by pokryl všechny ostatní sloupce i PERSON_ID. V tomto případě SQL Server provede index SEEK na indexu v PERSON_ID, pak to použije k vyhledání klíčů v seskupeném indexu v ADDRESS_ID a odtud vrátí všechna data ve všech ostatních sloupcích na stejném řádku.

Řekněme však, že chcete vyhledat všechny osoby ve městě, ale nepotřebujete další informace o adrese. Tentokrát by nejúčinnějším způsobem bylo vytvořit index na CITY a použít možnost INCLUDE pro pokrytí PERSON_ID. Tímto způsobem by jeden index hledání / skenování vrátil všechny informace, které potřebujete, aniž byste se museli uchýlit ke kontrole CLUSTERED indexu pro data PERSON_ID na stejném řádku.

Nyní řekněme, že oba tyto dotazy jsou vyžadovány, ale stále jsou poměrně těžké kvůli 1 miliardě záznamů. Ale je tu jeden speciální dotaz, který musí být opravdu rychlý. Tento dotaz chce všechny osoby na adresách, které byly MARKED_FOR_CHECKUP a které musí žít v New Yorku (ignorujte cokoli, co kontrola znamená, na tom nezáleží). Nyní možná budete chtít vytvořit třetí, filtrovaný index pro MARKED_FOR_CHECKUP a CITY, s INCLUDE pokrývající PERSON_ID a s filtrem, který říká CITY ='New York' a MARKED_FOR_CHECKUP =1. Tento index by byl šíleně rychlý, protože pokrývá pouze dotazy které splňují tyto přesné podmínky, a proto musí projít zlomkem dat ve srovnání s ostatními indexy.

(Tady zřeknutí se odpovědnosti, mějte na paměti, že plánovač provádění dotazů není hloupý, k vytvoření správných výsledků může použít více neshlukovaných indexů dohromady, takže výše uvedené příklady nemusí být ty nejlepší dostupné, protože je velmi těžké si představit, kdy byste to potřebovali 3 různé indexy pokrývající stejný sloupec, ale jsem si jistý, že tomu rozumíte.)

Typy indexů, jejich sloupce, zahrnuté sloupce, pořadí řazení, filtry atd. závisí zcela na situaci. Budete muset vytvořit krycí indexy, abyste uspokojili několik různých typů dotazů, a také přizpůsobené indexy vytvořené speciálně pro jednotlivé důležité dotazy. Každý index zabírá místo na pevném disku, takže vytváření zbytečných indexů je plýtvání a vyžaduje další údržbu, kdykoli se změní datový model, a plýtvá časem při defragmentaci a operacích aktualizace statistik... takže nechcete jen plácat index na všechno buď.

Experimentujte, učte se a zjistěte, co nejlépe vyhovuje vašim potřebám.



  1. Jak určit typ databáze pro dané připojení JDBC?

  2. Jak načíst velká data z mysql do php?

  3. Získání nezpracovaného řetězce dotazu SQL z připravených příkazů PDO

  4. Jak zpracuji jednoduché uvozovky v dotazu SQL v PHP?