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

Na jaký sloupec by měl být umístěn seskupený index?

Index, klastrovaný nebo neklastrovaný, může být použit optimalizátorem dotazů tehdy a pouze tehdy, je-li filtrován klíč nejvíce vlevo v indexu. Pokud tedy definujete index pro sloupce (A, B, C), podmínka WHERE na [email protected] , na [email protected] nebo na [email protected] AND [email protected] nebude plně využívat index (viz poznámka). To platí i pro podmínky připojení. Jakýkoli filtr WHERE, který obsahuje A vezme v úvahu index:[email protected] nebo [email protected] AND [email protected] nebo [email protected] AND [email protected] nebo [email protected] AND [email protected] AND [email protected] .

Pokud tedy ve vašem příkladu vytvoříte clustrovaný index na part_no jako klíč zcela vlevo, poté dotaz hledající konkrétní part_id nebude použijte index a na part-id musí existovat samostatný index bez klastrů .

Nyní k otázce, který z mnoha indexů by měl být shlukovaný jeden. Pokud máte několik vzorů dotazů, které jsou přibližně stejně důležité a četné a vzájemně si odporují, pokud jde o potřebné klíče (např. časté dotazy buď part_no nebo part_id ), pak vezmete v úvahu další faktory:

  • šířka :seskupený indexový klíč používá jako vyhledávací klíč všechny jiné indexy bez klastrů. Pokud tedy zvolíte široký klíč (řekněme dva sloupce s jednoznačným identifikátorem), rozšíříte všechny ostatní indexy, spotřebováváte tak více místa, generujete více IO a vše zpomalujete. Mezi stejně dobrými klíči z hlediska čtení tedy vyberte ten nejužší jako seskupený a širší udělejte bez seskupení.
  • spor :pokud máte specifické vzory vkládání a mazání, zkuste je fyzicky oddělit, aby se vyskytovaly v různých částech seskupeného indexu. Např. pokud se tabulka chová jako fronta se všemi vložkami na jednom logickém konci a se všemi mazáními na druhém logickém konci, zkuste rozmístit seskupený index tak, aby fyzické pořadí odpovídalo tomuto logickému pořadí (např. pořadí zařazování do fronty).
  • rozdělení :pokud je tabulka velmi velká a plánujete nasadit dělení, pak rozdělovacím klíčem musí být seskupený index. Typickým příkladem jsou historická data, která jsou archivována pomocí schématu rozdělení posuvných oken. I když entity mají logický primární klíč, jako je 'entity_id', klustrovaný index je tvořen sloupcem datetime, který se také používá pro funkci rozdělení.
  • stabilita :klíč, který se často mění, je špatným kandidátem na seskupený klíč, protože každý aktualizuje hodnotu seskupeného klíče a vynutí vše neklastrované indexy k aktualizaci vyhledávacího klíče, který ukládají. Protože aktualizace seskupeného klíče pravděpodobně přemístí záznam na jinou stránku, může to způsobit fragmentaci seskupeného indexu.

Poznámka:Ne úplně pákový efekt, protože někdy si engine vybere neshlukovaný index k skenování namísto seskupeného indexu jednoduše proto, že je užší a má tedy méně stránek ke skenování. V mém příkladu, pokud máte index na (A, B, C) a filtr WHERE na [email protected] a dotaz projekty C , index bude pravděpodobně použit, ale ne jako hledání, jako skenování, protože je stále rychlejší než úplné shlukované skenování (méně stránek).



  1. Jak ukládat pouze čas; není datum a čas?

  2. Oprava „CHYBA:  každý dotaz UNION musí mít stejný počet sloupců“ v PostgreSQL

  3. Verze Oracle ODP.NET agnostická alternativa

  4. Jak vybrat datum ze sloupce datum a čas?