W tabeli bez indeksu klastrowego (tabela sterty) strony danych nie są ze sobą połączone — więc przechodzenie przez strony wymaga wyszukaj mapę alokacji indeksu .
Tabela klastrowana ma jednak strony danych połączone na podwójnie połączonej liście - szybsze wykonywanie skanów sekwencyjnych. Oczywiście w zamian masz narzuty związane z utrzymaniem porządku stron danych na INSERT
, UPDATE
i DELETE
. Jednak tabela sterty wymaga drugiego zapisu do uprawnień.
Jeśli Twoje zapytanie ma RANGE
operator (np.:SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100
), wtedy tabela klastrowana (w gwarantowanej kolejności) byłaby bardziej wydajna - ponieważ mogłaby użyć stron indeksu do znalezienia odpowiednich stron danych. Sterta musiałaby zeskanować wszystkie wiersze, ponieważ nie może polegać na zamawianiu.
I oczywiście indeks klastrowy umożliwia wykonanie CLUSTERED INDEX SEEK, który jest praktycznie optymalny dla wydajności... sterta bez indeksów zawsze skutkowałaby skanowaniem tabeli.
A więc:
-
W przypadku przykładowego zapytania, w którym wybierasz wszystkie wiersze, jedyną różnicą jest podwójnie połączona lista, którą utrzymuje indeks klastrowy. Powinno to sprawić, że tabela klastrowana będzie odrobinę szybsza niż sterta z dużą liczbą wierszy.
-
W przypadku zapytania z
WHERE
klauzula, która może być (przynajmniej częściowo) spełniona przez indeks klastrowy, wyjdziesz z przodu dzięki kolejności - więc nie będziesz musiał skanować całej tabeli. -
W przypadku zapytania, które nie jest spełnione przez indeks klastrowy, jesteś prawie równy... znowu, jedyną różnicą jest ta podwójnie połączona lista do skanowania sekwencyjnego. W obu przypadkach jesteś nieoptymalny.
-
Dla
INSERT
,UPDATE
iDELETE
sterta może, ale nie musi wygrać. Sterta nie musi utrzymywać porządku, ale wymaga drugiego zapisu do uprawnień. Myślę, że względna różnica w wydajności byłaby znikoma, ale byłaby też dość zależna od danych.
Microsoft ma biały dokument który porównuje indeks klastrowy z równoważnym indeksem nieklastrowym na stercie (nie dokładnie taki sam, jak omówiłem powyżej, ale zbliżony). Ich wniosek polega w zasadzie na umieszczeniu indeksu klastrowego na wszystkich tabelach. Zrobię co w mojej mocy, aby podsumować ich wyniki (zwróć uwagę, że tak naprawdę porównują tutaj indeks nieklastrowy z indeksem klastrowym – ale myślę, że jest stosunkowo porównywalny):
INSERT
wydajność:indeks klastrowy wygrywa o około 3% z powodu drugiego zapisu potrzebnego do sterty.UPDATE
wydajność:indeks klastrowy wygrywa o około 8% z powodu drugiego wyszukiwania potrzebnego do sterty.DELETE
wydajność:indeks klastrowy wygrywa o około 18% z powodu potrzebnego drugiego wyszukiwania i drugiego usunięcia potrzebnego z uprawnień dla sterty.- pojedynczy
SELECT
wydajność:indeks klastrowy wygrywa o około 16% z powodu drugiego wyszukiwania potrzebnego do sterty. - zakres
SELECT
wydajność:indeks klastrowy wygrywa o około 29% dzięki losowemu porządkowaniu stosu. - równoczesne
INSERT
:tabela sterty wygrywa o 30% pod obciążeniem z powodu podziałów stron dla indeksu klastrowanego.