it-swarm-eu.dev

Tvrdé a rychlé pravidlo pro zahrnutí sloupců do indexu

Existuje nějaké tvrdé a rychlé pravidlo, které rozhoduje o tom, jaké sloupce a v jakém pořadí má být zahrnuto. Zahrnuto do neskupovaného indexu. Právě jsem četl tento příspěvek https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index a zjistil jsem, že pro následující dotaz :

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5

Plakát navrhl vytvořit index takto:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(EmployeeID, DepartmentID)
  INCLUDE (Lastname)

tady přichází moje otázka, proč nemůžeme vytvořit index takhle

CREATE NONCLUSTERED INDEX NC_EmpDep 
      ON Employee( EmployeeID, DepartmentID, LastName)

nebo

    CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

a co vede plakát k rozhodnutí ponechat sloupec Příjmení zahrnutý. Proč ne jiné sloupce? a jak rozhodnout, v jakém pořadí bychom měli sloupce ponechat?

38
Rocky Singh

Tento návrh indexu podle marc_s je nesprávný. Přidal jsem komentář. (A byla to také moje odpověď!)

Index pro tento dotaz by byl

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (Lastname, EmployeeID)

Index je obvykle

CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)

Kde:

  • KeyColList = Klíčové sloupce = používá se pro omezení řádků a zpracování
    KDE, PŘIPOJTE SE, OBJEDNÁVEJTE, SKUPINUJTE atd
  • NonKeyColList = Neklíčové sloupce = používané v SELECT a agregaci (např. SUM (col)) po výběru/omezení
48
gbn

JNK a gbn dali skvělé odpovědi, ale stojí za zvážení i celkový obraz - nejen zaměření na jediný dotaz. Ačkoli tento konkrétní dotaz může mít prospěch z indexu (# 1):

Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)

Tento index vůbec nepomůže, pokud se dotaz mírně změní, například:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'

To by vyžadovalo index (# 2):

Employee(DepartmentID, LastName) INCLUDE (EmployeeID)

Představte si, že jste v oddělení 5 měli 1 000 zaměstnanců. Pomocí indexu 1 vyhledejte všechny Smithy, měli byste hledat všech 1 000 řádků v oddělení 5, protože zahrnuté sloupce nejsou součástí klíče. Pomocí indexu # 2 můžete vyhledávat přímo na Oddělení 5, Příjmení Smith.

Index # 2 je tedy užitečnější při údržbě širšího rozsahu dotazů - ale cena je více nafouknutým indexovým klíčem, který způsobí, že stránky bez listů indexu budou větší. Každý systém bude jiný, takže zde není žádné pravidlo.


Jako vedlejší poznámku stojí za zmínku, že pokud EmployeeID byl klíčem klastru pro tuto tabulku - za předpokladu, že je klastrovaný index - pak nemusíte zahrnout EmployeeID - je přítomen ve všech neslastovaných indexech, což znamená, že index # 2 by mohl být

Employee(DepartmentID, LastName)
19
Jim McLeod

Nejsem si jistý, jak jsi dostal ten první. Pro tento dotaz bych pro tento dotaz použil:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (EmployeeID, Lastname)

V SQL neexistuje „tvrdé a rychlé pravidlo“ pro téměř cokoli.

Pro váš příklad je však jediné pole, které index použije, DepartmentID, protože je v klauzuli WHERE.

Ostatní pole musí být odtud snadno přístupná. Vyberete na základě DepartmentID, pak INCLUDE má tato pole v listovém uzlu indexu.

Nechcete používat jiné příklady, protože by pro tento index nefungovaly.

Myslete na index jako na telefonní seznam. Většina telefonních seznamů je řazena podle příjmení, křestního jména, středního iniciálu. Pokud znáte něčí křestní jméno, ale ne jeho příjmení, telefonní seznam vám není k ničemu, protože nemůžete hledat křestní jméno na základě indexu v telefonním seznamu.

Pole INCLUDE jsou jako telefonní číslo, adresa atd. Další informace pro každý záznam v knize.

ÚPRAVA:

Pro další vysvětlení, proč nepoužívat:

CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

Tento index je užitečný pouze v případě, že máte EmployeeID nebo OBA EmployeeID a LastName v klauzuli WHERE. Toto je do značné míry NAPROTI toho, co potřebujete pro tento dotaz.

7
JNK

Myslím, že byste stále mohli používat index (employee_id, department_id), ale do fráze, kterou byste chtěli uvést, byste museli zahrnout řádek „fiktivní“, například: „employee_id = zaměstnanec_id)

  • mít index na (employee_id, departemnent_id),
  • museli hledat/omezovat pouze na department_id
  • protože věděl, že index nebude používat od nesprávného pořadí (nebo se věci nyní změnily, a následující „trik“ již není potřeba. Jsem „starý“?) .
  • Používáte „starý“ tricK?

    vyberte * ze Zaměstnaneckého emp
    kde emp.employee_id = emp.employee_id
    a emp.department_id = 5

(Takže se nezaměřuji na zahrnutí části zde Příjmení, ale na ano/nebo nevyužití klíče.)

S přátelským pozdravem,

Miguell

0
Miguel Leeuwe