Jednym z powodów, aby preferować INCLUDE
kolumny klucza, jeśli nie potrzebujesz tej kolumny w kluczu, jest dokumentacja. To sprawia, że ewolucja indeksów będzie znacznie łatwiejsza w przyszłości.
Biorąc pod uwagę twój przykład:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Ten indeks jest najlepszy, jeśli zapytanie wygląda następująco:
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
Oczywiście nie powinieneś wstawiać kolumn, INCLUDE
jeśli możesz uzyskać dodatkową korzyść z posiadania ich w kluczowej części. Oba poniższe zapytania faktycznie wolą col2
kolumnę w kluczu indeksu.
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
Załóżmy, że tak nie jest i mamy to col2
w INCLUDE
klauzuli, ponieważ po prostu nie ma korzyści z posiadania go w części drzewa indeksu.
Kilka lat do przodu.
Musisz dostroić to zapytanie:
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
Aby zoptymalizować to zapytanie, świetny byłby następujący indeks:
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
Jeśli sprawdzisz, jakie indeksy masz już w tej tabeli, twój poprzedni indeks może nadal tam być:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Teraz wiesz o tym Col2
i Col3
nie są częścią drzewa indeksów, a zatem nie są używane do zawężania zakresu indeksu odczytu ani do porządkowania wierszy. Można raczej bezpiecznie dodać another_column
na końcu kluczowej części indeksu (po col1
). Ryzyko zniszczenia czegokolwiek jest niewielkie:
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
Indeks ten będzie większy, co nadal wiąże się z pewnym ryzykiem, ale ogólnie lepiej jest rozszerzyć istniejące indeksy niż wprowadzać nowe.
Jeśli miałbyś indeks bez INCLUDE
, nie wiedziałbyś, jakie zapytania przerwałbyś, dodając another_col
zaraz potem Col1
.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
Co się stanie, jeśli dodasz another_col
pomiędzy Col1
i Col2
? Czy ucierpią inne zapytania?
Istnieją inne „zalety” w INCLUDE
porównaniu z kluczowymi kolumnami, jeśli dodasz te kolumny tylko po to, aby uniknąć pobierania ich z tabeli . Uważam jednak, że najważniejszy jest aspekt dokumentacji.
Odpowiedzieć na Twoje pytanie:
jakie wytyczne zasugerowałbyś przy ustalaniu, czy utworzyć indeks obejmujący z klauzulą INCLUDE, czy bez?
Jeśli dodasz kolumnę do indeksu wyłącznie w celu udostępnienia tej kolumny w indeksie bez odwiedzania tabeli, umieść ją w INCLUDE
klauzuli.
Jeśli dodanie kolumny do klucza indeksu przynosi dodatkowe korzyści (np. Dla order by
lub ponieważ może zawęzić zakres odczytu indeksu), dodaj ją do klucza.
Dłuższą dyskusję na ten temat możesz przeczytać tutaj:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes