it-swarm.it

Regola hard e fast per includere colonne nell'indice

Esistono regole rigide e veloci per decidere quali colonne e in quale ordine devono essere inserite Incluso in un indice non cluster. Stavo solo leggendo questo post https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index e l'ho trovato per la seguente query :

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

Il poster ha suggerito di creare un indice come questo:

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

ecco la mia domanda: perché non possiamo fare un indice come questo

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

o

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

e cosa porta il poster a decidere di includere la colonna LastName. Perché non altre colonne? e come decidere in quale ordine dovremmo tenere le colonne lì?

38
Rocky Singh

Quel suggerimento dell'indice di marc_s è sbagliato. Ho aggiunto un commento (Ed è stata accettata anche la mia risposta!)

L'indice per questa query sarebbe

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

Un indice è in genere

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

Dove:

  • KeyColList = Colonne chiave = utilizzato per la limitazione e l'elaborazione delle righe
    DOVE, ISCRIVITI, ORDINA PER, GRUPPO PER ecc
  • NonKeyColList = Colonne non chiave = utilizzate in SELECT e aggregazione (ad es. SUM (col)) dopo selezione/restrizione
48
gbn

JNK e gbn hanno dato ottime risposte, ma vale anche la pena considerare il quadro generale, non solo concentrarsi su una singola query. Sebbene questa particolare query possa beneficiare di un indice (n. 1):

Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)

Questo indice non aiuta affatto se la query cambia leggermente, come ad esempio:

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

Ciò richiederebbe l'indice (n. 2):

Employee(DepartmentID, LastName) INCLUDE (EmployeeID)

Immagina di avere 1.000 dipendenti nel Dipartimento 5. Usando l'indice n. 1, per trovare tutti gli Smith, dovresti cercare tutte le 1.000 righe del Dipartimento 5, poiché le colonne incluse non fanno parte della chiave. Usando l'indice n. 2, puoi cercare direttamente al Dipartimento 5, LastName Smith.

L'Indice n. 2 è quindi più utile per servire una gamma più ampia di query, ma il costo è una chiave di indice più gonfia, che ingrandirà le pagine non foglia dell'indice. Ogni sistema sarà diverso, quindi non esiste una regola empirica qui.


Come nota a margine, vale la pena sottolineare che se EmployeeID era la chiave di clustering per questa tabella - presupponendo un indice cluster - quindi non è necessario includere EmployeeID - è presente in tutti gli indici non cluster, il che significa che l'indice n. 2 potrebbe semplicemente essere

Employee(DepartmentID, LastName)
19
Jim McLeod

Non sono sicuro di come l'hai preso per primo. Per me, per quella query, vorrei usare:

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

Non esiste una "regola rigida e veloce" per praticamente qualsiasi cosa in SQL.

Ma, per il tuo esempio, l'unico campo che verrà utilizzato dall'indice è DepartmentID perché è nella clausola WHERE.

Gli altri campi devono solo essere facilmente accessibili da lì. Si seleziona in base a DepartmentID quindi INCLUDE ha quei campi nel nodo foglia dell'indice.

Non vuoi usare altri esempi perché non funzionerebbero per questo indice.

Pensa a un indice come a una rubrica. La maggior parte delle rubriche telefoniche sono ordinate per cognome, nome, medio iniziale. Se conosci il nome di qualcuno, ma non il suo cognome, la rubrica non ti serve perché non puoi cercare il nome in base all'ordine dell'indice della rubrica.

I campi INCLUDE sono come il numero di telefono, l'indirizzo, ecc. Altre informazioni per ogni voce nel libro.

EDIT:

Per chiarire ulteriormente perché non utilizzare:

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

Questo indice è utile solo se hai EmployeeID o ENTRAMBI EmployeeID e LastName nel tuo WHERE clausola. Questo è praticamente il OPPOSTO di quello che ti serve per questa query.

7
JNK

Penso che potresti essere ancora in grado di utilizzare l'indice (employee_id, department_id), ma dovresti includere una riga 'fittizia' nella frase where, come: "employee_id = employee_id)

  • avendo un indice su (employee_id, departemnent_id),
  • dover cercare/limitare solo su un ID_gruppo
  • sapendo che non utilizzerà l'indice poiché l'ordine sbagliato (o le cose sono cambiate ormai, e il seguente "trucco" non è più necessario. Sono un "vecchio"?) .
  • Usa il "vecchio" tricK?

    selezionare * da Imp. dipendente
    dove emp.employee_id = emp.employee_id
    e emp.department_id = 5

(Quindi non mi sto concentrando sulla parte di inclusione qui di Lastname, ma sul sì/o non essere usato della chiave.)

Cordiali saluti,

Miguell

0
Miguel Leeuwe