Un motivo per preferire INCLUDE
le colonne chiave se non è necessaria quella colonna nella chiave è la documentazione. Ciò rende gli indici in evoluzione molto più facili in futuro.
Considerando il tuo esempio:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Tale indice è il migliore se la tua query è simile alla seguente:
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
Ovviamente non dovresti inserire colonne INCLUDE
se puoi ottenere un ulteriore vantaggio dal fatto di averle nella parte chiave. Entrambe le seguenti query preferirebbero effettivamente la col2
colonna nella chiave dell'indice.
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
Supponiamo che questo non sia il caso e lo abbiamo col2
nella INCLUDE
clausola perché non c'è proprio alcun vantaggio di averlo nella parte ad albero dell'indice.
Avanzamento veloce di alcuni anni.
È necessario ottimizzare questa query:
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
Per ottimizzare quella query, il seguente indice sarebbe ottimo:
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
Se controlli quali indici hai già su quella tabella, il tuo indice precedente potrebbe essere ancora lì:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Ora lo sai Col2
e Col3
non fanno parte dell'albero dell'indice e non vengono quindi utilizzati per restringere l'intervallo dell'indice di lettura né per ordinare le righe. È piuttosto sicuro aggiungere another_column
alla fine della parte chiave dell'indice (dopo col1
). C'è poco rischio di rompere qualcosa:
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
Tale indice diventerà più grande, il che comporta ancora alcuni rischi, ma è generalmente meglio estendere gli indici esistenti rispetto a introdurne di nuovi.
Se avessi un indice senza INCLUDE
, non potresti sapere quali query interromperesti aggiungendo another_col
subito dopo Col1
.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
Cosa succede se aggiungi another_col
tra Col1
e Col2
? Altre domande soffriranno?
Ci sono altri "vantaggi" delle INCLUDE
colonne chiave vs. se aggiungi quelle colonne solo per evitare di recuperarle dalla tabella . Tuttavia, considero l'aspetto della documentazione il più importante.
Per rispondere alla tua domanda:
quali linee guida suggeriresti per determinare se creare un indice di copertura con o senza la clausola INCLUDE?
Se aggiungi una colonna all'indice al solo scopo di renderla disponibile nell'indice senza visitare la tabella, inseriscila nella INCLUDE
clausola.
Se l'aggiunta della colonna alla chiave dell'indice comporta ulteriori vantaggi (ad es. Per order by
o perché può restringere l'intervallo dell'indice di lettura), aggiungerla alla chiave.
Puoi leggere una discussione più lunga su questo qui:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes