2011-01-02 7 views
6

Zakładając, że tabela zawiera wystarczające informacje, aby uzasadnić wyszukiwanie indeksu, przy jakiej liczności SQL Server (lub PostgreSQL) zdecyduje się na skanowanie indeksu?Na jakiej liczności SQL Server przełącza się na skanowanie indeksu (w porównaniu do wyszukiwania)?

Powodem, dla którego o to pytam, było wcześniejsze wysłanie pytania (link), w którym dwa zapytania zostały wykonane z tą samą szybkością, ale jeden nie próbował użyć indeksu do przetworzonych kolumn. Po SQL Server zasugerowałem umieścić obejmujący indeks, który zawarte badanych kolumn (zasugerował to dla obu zapytań), zacząłem szukać powodów, dla których miałoby to takie dziwne sugestie.

Eksperymentowałem z tworzeniem indeksów obejmujących i złożonych, ale oba wykonywane w tym samym czasie (mówimy o 3 milionach wierszy).

W końcu doszedłem do wniosku, że wynika to z bardzo dużej liczności danych. Każdy wiersz jest unikalny. Przypuszczam, że to spowodowało, że serwer SQL wybrał skanowanie indeksu. Jednak zapytanie to "WHERE Col1>? AND Col2 <?", Więc jest to trochę mylące.

Moje pytania są następujące:

  1. Na co liczność BĘDZIE RDBMS zawsze zdecydować się na indeksie skanować?
  2. Czy ktoś może wyjaśnić, dlaczego SQL Server nie użyłby indeksu, gdy instrukcja WHERE wskazywałaby, że ma to sens?

Dołączyłem plan wykonania. alt text

Odpowiedz

5

Pod względem SQL Servera został on określony jako punkt krytyczny, którego wpis na blogu Kimberley jest dobrze przeczytany. http://www.sqlskills.com/BLOGS/KIMBERLY/category/The-Tipping-Point.aspx

Punkt krytyczny jest wytyczną dotyczącą 25% -33% całkowitej liczby stron w tabeli, wyrażonych jako wiersze, np. Strony danych o wielkości 10 tys. Dałoby punkt krytyczny 2500-3333 wierszy. Zgodnie z wytycznymi jest to całkiem niezłe i tak dobre, jak to tylko możliwe - pamiętaj, że silnik planu zapytań to czarna skrzynka, a podczas gdy dostarczy ci plan zapytań, to tylko mówi, co zdecydował, a nie dlaczego.

Jeśli chodzi o przechylanie indeksu pokrywającego, co nie jest w rzeczywistości bardzo łatwe, nawet przy 100% wybranych danych indeksu pokrywającego nadal będzie wymagać przeszukiwania w większości przypadków.

To ma sens, jeśli uważasz, że optymalizator kosztów nie przypisuje żadnych kosztów rzeczywistych do hierarchii stron indeksowych, każda kosztuje tylko wyższy dostęp do stron liści indeksu. W tym momencie skanowanie lub szukanie 100% indeksu pokrywającego kosztuje to samo.

Znalazłem z własnego eksperymentu (http://sqlfascination.com/2009/11/07/can-a-covering-nc-index-be-tipped), używając klauzuli between, która spowodowałaby skanowanie, ale inne, gdzie klauzule nie - z tego, co mogłem powiedzieć, to było wyłącznie do trasy przez silnik kwerendy.

+0

Świetna odpowiedź @Andrew. To wyjaśnia mi to ładnie i wyjaśnia, dlaczego SQL Server wybrał skanowanie indeksu. – IamIC

+0

@Andrew: "Jeśli chodzi o przechylanie indeksu pokrywającego, to w rzeczywistości nie jest to łatwe, nawet przy 100% wybranych danych indeks obejmujący nadal będzie wymagał przeszukiwania w większości przypadków" - dlaczego tak jest? – IamIC

+0

Silnik planu zapytań to optymalizator oparty na kosztach, ponieważ dostęp do hierarchii indeksów kosztuje 0, a wyszukiwanie każdej strony liścia w indeksie to taki sam koszt, jak skanowanie każdej strony liścia w indeksie (pod względem kosztów). W zależności od użytej klauzuli where widziałem, że robi to jedno i drugie, ale trzeba było sporo wysiłku, aby go zeskanować. Domyślnie szukano – Andrew

3

Zwykle nie jest to dobre pytanie w PostgreSQL, ponieważ faktyczny wybór planu jest bardziej skomplikowany. To zależy od wielkości tabeli, ustawień pamięci i innych części zapytania. Zwykle otrzymasz zwykły skan indeksu tylko wtedy, gdy wybierzesz bardzo mało wierszy. Oprócz tego otrzymasz skanowanie indeksu mapy bitowej, aby powiedzieć 40% selektywności w prostych eksperymentach.

+0

Dzięki @Peter. Wspomniałeś o indeksach Bitmap (potomek M/Caché). W jakich warunkach są używane? (niska liczebność zgaduję) – IamIC

+0

Ps. Jestem nowy w PostgreSQL, ale doświadczony w SQL Server. – IamIC

+0

Skanowanie indeksu bitmapowego nie wykorzystuje indeksu bitmapy (który nie istnieje w PostgreSQL). Jest to rodzaj skanowania indeksu polegającego na użyciu bitmap po drodze. Jak napisałem powyżej, są one używane gdzieś pomiędzy regularnymi skanami indeksu i sekwencyjnymi skanami. –