Mam tabelę z indeksem wielokolumnowym i mam wątpliwości co do właściwego sortowania indeksów, aby uzyskać maksymalną wydajność zapytań.
Scenariusz:
PostgreSQL 8.4, tabela z około milionem wierszy
Wartości w kolumnie c1 mogą mieć około 100 różnych wartości . Możemy założyć, że wartości są równomiernie rozłożone, więc mamy około 10000 wierszy na każdą możliwą wartość.
Kolumna c2 może mieć 1000 różnych wartości . Mamy 1000 wierszy dla każdej możliwej wartości.
Podczas wyszukiwania danych warunek zawsze zawiera wartości dla tych dwóch kolumn, więc tabela ma indeks wielokolumnowy łączący c1 i c2. Czytałem o tym, jak ważne jest prawidłowe uporządkowanie kolumn w indeksie wielokolumnowym, jeśli masz zapytania wykorzystujące tylko jedną kolumnę do filtrowania. W naszym scenariuszu tak nie jest.
Moje pytanie brzmi:
Biorąc pod uwagę fakt, że jeden z filtrów wybiera znacznie mniejszy zestaw danych, czy mogę poprawić wydajność, jeśli pierwszy indeks jest najbardziej selektywny (ten, który pozwala na mniejszy zestaw)? Nigdy nie zastanawiałem się nad tym pytaniem, dopóki nie zobaczyłem grafiki z przywoływanego artykułu:
Zdjęcie pochodzi z przywoływanego artykułu o indeksach wielokolumnowych .
W zapytaniach do filtrowania są używane wartości z dwóch kolumn. Nie mam zapytań używających tylko jednej kolumny do filtrowania. Wszystkie z nich są: WHERE c1=@ParameterA AND c2=@ParameterB
. Istnieją również takie warunki:WHERE c1 = "abc" AND c2 LIKE "ab%"
źródło
Jeśli, jak mówisz, zapytania dotyczące tych 2 kolumn są sprawdzeniami równości obu kolumn, np .:
nie zawracaj sobie tym głowy. Wątpię, czy będzie jakakolwiek różnica, a jeśli będzie, to będzie ona nieistotna. Zawsze możesz oczywiście przetestować swoje dane i ustawienia serwera. Różne wersje DBMS mogą zachowywać się nieco inaczej w zakresie optymalizacji.
Kolejność w indeksie miałaby znaczenie dla innych typów zapytań, sprawdzania tylko jednej kolumny lub warunków nierówności lub warunków dla jednej kolumny i grupowania w drugiej itd.
Gdybym miał wybrać jedno z dwóch zamówień, wybrałbym najpierw kolumnę mniej selektywną. Rozważ tabelę z kolumnami
year
imonth
. Bardziej prawdopodobne jest, że potrzebujeszWHERE year = 2000
warunku lub aWHERE year BETWEEN 2000 AND 2013
lub aWHERE (year, month) BETWEEN (1999, 6) AND (2000, 5)
.Zapytanie tego typu
WHERE month = 7 GROUP BY year
może być potrzebne (Znajdź osoby urodzone w lipcu), ale byłoby rzadziej. Zależy to oczywiście od rzeczywistych danych przechowywanych w tabeli. Wybierz na razie jedno zamówienie, powiedz,(c1, c2)
a zawsze możesz później dodać kolejny indeks(c2, c1)
.Zaktualizuj, po komentarzu PO:
Ten typ zapytania jest dokładnie warunkiem zakresu w
c2
kolumnie i wymagałby(c1, c2)
indeksu. Jeśli masz również zapytania typu odwrotnego:byłoby dobrze, gdybyś miał również
(c2, c1)
indeks.źródło