Postanowiłem trochę zagłębić się w to pytanie i znalazłem kilka interesujących dokumentów mówiących o tym, jak i kiedy używać, a może lepiej, a nie (wymuszać) stosowanie indeksu nieklastrowanego.
Jak sugerują komentarze Johna Eisbrenera , jednym z najczęściej cytowanych, nawet na innych blogach, jest ten interesujący artykuł Kimberly L. Tripp:
ale nie jest to jedyny, jeśli jesteś zainteresowany, możesz spojrzeć na te strony:
Jak widać, wszystkie poruszają się wokół koncepcji punktu krytycznego .
Cytat z artykułu KL Tripp
Jaki jest punkt krytyczny?
Jest to punkt, w którym liczba zwracanych wierszy „ nie jest już wystarczająco selektywna ”. SQL Server decyduje się NIE używać indeksu nieklastrowanego do wyszukiwania odpowiednich wierszy danych i zamiast tego wykonuje skanowanie tabeli.
Gdy SQL Server używa indeksu nieklastrowego na stercie, w zasadzie pobiera listę wskaźników do stron tabeli podstawowej. Następnie używa tych wskaźników, aby pobrać wiersze za pomocą serii operacji o nazwie Wyszukiwanie identyfikatorów wierszy (RID). Oznacza to, że przynajmniej użyje tyle odczytów strony, ile zwróconych wierszy, i być może więcej. Proces jest nieco podobny z indeksem klastrowym jak tabela podstawowa, z tym samym rezultatem: więcej odczytów.
Ale kiedy nastąpi ten punkt krytyczny?
Oczywiście, jak większość rzeczy w tym życiu, zależy ...
Nie poważnie, występuje między 25% a 33% liczby stron w tabeli, w zależności od liczby wierszy na stronie. Ale jest więcej czynników, które należy wziąć pod uwagę:
Cytat z artykułu ITPRoToday
Inne czynniki wpływające na punkt krytyczny Chociaż koszt wyszukiwania RID jest najważniejszym czynnikiem wpływającym na punkt krytyczny, istnieje wiele innych czynników:
- Fizyczne operacje we / wy są znacznie wydajniejsze podczas skanowania indeksu klastrowego. Dane indeksu klastrowego są umieszczane sekwencyjnie na dysku w kolejności indeksu. W rezultacie na dysku jest bardzo mało bocznego ruchu głowicy, co poprawia wydajność we / wy.
- Gdy silnik bazy danych skanuje indeks klastrowany, wie, że istnieje duże prawdopodobieństwo, że kilka kolejnych stron ścieżki dysku będzie nadal zawierało dane, których potrzebuje. Więc zaczyna czytać z wyprzedzeniem w kawałkach o wielkości 64 KB zamiast zwykłych stron o wielkości 8 KB. Powoduje to również szybsze operacje we / wy.
Teraz, jeśli ponownie wykonam moje zapytania za pomocą statystyk IO:
SET STATISTICS IO ON;
SELECT id, foo, bar, nki FROM my_table WHERE nki < 20000 ORDER BY nki ;
SET STATISTICS IO OFF;
Logical reads: 312
SET STATISTICS IO ON;
SELECT id, foo, bar, nki FROM my_table WITH(INDEX(IX_my_TABLE));
SET STATISTICS IO OFF;
Logical reads: 41293
Drugie zapytanie wymaga więcej logicznych odczytów niż pierwsze.
Czy powinienem unikać indeksu nieklastrowanego?
Nie, indeks klastrowy może być przydatny, ale warto poświęcić trochę czasu i podjąć dodatkowy wysiłek, analizując, co próbujesz osiągnąć za jego pomocą.
Cytat z artykułu KL Tripp
Co powinieneś zrobić? To zależy. Jeśli dobrze znasz swoje dane i przeprowadzasz obszerne testy, możesz rozważyć skorzystanie z podpowiedzi (jest kilka sprytnych rzeczy, które możesz zrobić programowo w SP, postaram się poświęcić temu post wkrótce). Jednak znacznie lepszym wyborem (jeśli w ogóle jest to możliwe) jest rozważenie pokrycia (to naprawdę moja główna uwaga :). W moich zapytaniach zasłanianie jest nierealistyczne, ponieważ moje zapytania wymagają wszystkich kolumn (zły WYBIERZ *), ale jeśli twoje zapytania są węższe ORAZ mają wysoki priorytet, lepiej jest użyć indeksu pokrycia (w wielu przypadkach) zamiast podpowiedzi, ponieważ indeks, który obejmuje zapytanie, nigdy nie daje wskazówek.
To na razie odpowiedź na zagadkę, ale zdecydowanie jest o wiele więcej do zrobienia. Punkt krytyczny może być bardzo dobrą rzeczą - i zwykle działa dobrze. Ale jeśli okaże się, że możesz wymusić indeks i uzyskać lepszą wydajność, możesz przeprowadzić dochodzenie i sprawdzić, czy to jest to. Zastanów się, jak prawdopodobne jest podpowiedź, a teraz wiesz, gdzie możesz się skupić.