Jeden indeks czy dwa?

11

Mam następujący indeks utworzony w tabeli w mojej bazie danych:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Serwer sugeruje następujący indeks „brakujących”:

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Logiczne wydaje mi się poprawienie istniejącej definicji indeksu w celu uwzględnienia sugerowanych kolumn zamiast tworzenia nowego indeksu, który należy utrzymać. Kwerenda, która wybiera dla col1 i col2, mogłaby korzystać z indeksu 1 równie skutecznie jak index2. Czy mam rację, czy może coś brakuje?

Paweł
źródło

Odpowiedzi:

12

I tak wkracza sztuka strategii dostrajania wydajności i indeksowania ...

Logiczne wydaje mi się poprawienie istniejącej definicji indeksu w celu uwzględnienia sugerowanych kolumn

Wezmę twój cytat i napiszę trzecią definicję indeksu:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

To powinno być CREATE INDEXstwierdzenie, które odpowiada cytowanemu oświadczeniu.

To może być rozsądne rozwiązanie, ale to zależy . Oto kilka przykładów, kiedy mówię, że to zależy.

Jeśli masz wspólne obciążenie, które składa się głównie z takich zapytań:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Wtedy twój idx_index1indeks byłby solidny. Idealnie wąski, jest to indeks, który spełnia to zapytanie bez żadnych obcych danych (nie biorąc pod uwagę definicji indeksu klastrowego, jeśli w ogóle).

Ale jeśli masz obciążenie, które składa się głównie z zapytań:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Wtedy idx_index2byłoby mądre, ponieważ jest to, co nazywa się pokrywającą indeks zapobiegając potrzebę kluczowego przeglądowej powrót do indeksu klastrowego (lub RID lookup plecami do sterty). Ta definicja indeksu nieklastrowego obejmowałaby wyłącznie wszystkie dane, których potrzebuje zapytanie.

Z twoim zaleceniem byłoby dobrze pasować do zapytania takiego jak:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Twoje idx_index3zalecenie byłoby indeksem obejmującym, który spełnia kryteria wyszukiwania dla powyższego zapytania.

Chodzi mi o to, że chodzi o pojedyncze pytanie, na które nie możemy ostatecznie odpowiedzieć. Wszystko zależy od typowego i częstego obciążenia pracą. Oczywiście zawsze możesz zdefiniować wszystkie trzy z tych indeksów, aby obsłużyć każdy przykładowy typ zapytania, ale wtedy pojawia się pytanie o konserwację, która będzie wymagana do aktualizacji tych indeksów (pomyśl: INSERTs, UPDATEs, DELETEs). To narzut indeksów.

Musisz dokładnie przeanalizować i ocenić obciążenie pracą oraz ustalić, gdzie będą najlepsze korzyści. Jeśli pierwsze przykładowe zapytanie jest najczęściej wykonywane dziesiątki razy na sekundę, a istnieje bardzo rzadkie zapytanie, takie jak trzecie przykładowe zapytanie, wówczas nie ma sensu przesadzać stron poziomu indeksu za pomocą INCLUDEniekluczowe kolumny. Wszystko zależy od obciążenia pracą.

Jeśli rozumiesz ostrożne strategie indeksowania i rozumiesz swoje wspólne obciążenie pracą, wówczas stosując oba te sposoby będziesz w stanie wymyślić najlepszą możliwą drogę.

Thomas Stringer
źródło
Będę musiał to trochę przetrawić, ale wydaje się, że to dobra odpowiedź. Zakładam, że to literówka, że ​​zdefiniowany przez ciebie „indeks3” ma col3 jako kolumnę równości ORAZ kolumnę dołączoną?
paulH
Tak :-) Dobry chwyt. Zedytowałem to.
Thomas Stringer
Nie wspominając już o tym, że jeśli tabela zawiera tylko kolumny 1-6, indeksowanie 1 i 2 i uwzględnianie 3-5 jest dość głupie.
Kenneth Fisher
1
@KennethFisher - dlaczego to byłoby głupie? Wydaje się rozsądnym rozwiązaniem, jeśli uzasadnia to struktura bazy danych i obciążenie pracą. Np. Jeśli masz zapytanie, które wybiera kolumny 1-5 na podstawie wartości kolumn 1 i 2, a być może kolumna 6 jest kolumną nvarchar (max), z którą nie chcesz rozszerzać swojego indeksu.
paulH
1
@paulH Prawdopodobnie to tylko moja opinia, ale w momencie, gdy dodałeś wystarczającą liczbę kolumn do włączenia, że ​​twój indeks zawiera 90 +% twoich kolumn w tabeli, nadęłeś swój indeks do tego stopnia, że ​​dodatkowy odczyt, aby przejść do tabeli samo w sobie nie jest aż tak ważne. Teraz są z pewnością wyjątki .. jeśli cols 1-5 są intami, a col6 jest varchar (max), to mógłbym to zrobić. Ale generalnie przyjrzałbym się tym BARDZO uważnie.
Kenneth Fisher
7

Naprawdę masz rację i odkryłeś, dlaczego dla DBA ważne jest, aby zawsze przeglądać „sugestie” przedstawione przez brakujące indeksy DMV itp.

Weź pod uwagę, że sugestie oferowane przez brakujące indeksy DMV są przedstawiane osobno, co oznacza, że ​​SQL Server zdecydował, że indeks zalecanej struktury będzie korzystny dla zapytania, niezależnie od tego, jakie inne struktury indeksów mogą już istnieć.

John Sansom
źródło
3

Trochę więcej na temat jednej z implikacji odpowiedzi Thomasa:

Powiedział:

Oczywiście zawsze możesz zdefiniować wszystkie trzy z tych indeksów, aby obsłużyć każdy przykładowy typ zapytania, ale wtedy pojawia się pytanie o konserwację, która będzie wymagana do aktualizacji tych indeksów (pomyśl: INSERTs, UPDATEs, DELETEs). To narzut indeksów.

Kolejne duże pytanie brzmi: jak często tabela jest aktualizowana?

Rozważ najpierw przykład tabeli, która jest stale aktualizowana, na przykład ORDERStabela detaliczna odzwierciedlająca aktywność konsumentów w witrynie ... tam, chcesz być sumienny, mając wiele indeksów, ponieważ zwiększają one pracę wykonywaną przez ciągłe aktualizacje, a zatem stale wpływa na wydajność bazy danych.

Z drugiej strony, rozważ tabelę, która jest aktualizowana tylko w ramach konfiguracji strony internetowej - tabela jest aktualizowana RAZ dla większości wartości, a wartości rzadko dodawane - tam spowolnienia aktualizacji prawie nie są brane pod uwagę. Wiele indeksów może spowolnić odbudowywanie i ponowne indeksowanie baz danych, ale o ile są one wystarczająco szybkie, POCZUJ DARMO: jeśli wiele indeksów przyspieszy odczyty, idź.

Środkowym przypadkiem może być tabela, która zwykle jest aktualizowana tylko w procesie wsadowym przez noc. Tam spowolnienia aktualizacji z wielu indeksów nie wpłynęłyby na wydajność w ciągu dnia - wpłynęłyby one tylko na (1) czas potrzebny na uruchomienie tej nocnej konserwacji wsadowej, (2) na wydajność wszystkich współbieżnych procesów oraz (3) czas potrzebny na zadania związane z obsługą bazy danych, takie jak reorganizacja indeksu. Tak długo, jak procesy na tych 3 arenach działają wystarczająco szybko dla Ciebie ... utwórz indeksy, które przyspieszą zapytania.

HTH ...

Doug_Ivison
źródło