Częściowy indeks to dobry pomysł aby wykluczyć połowę rzędów tabeli, których oczywiście nie potrzebujesz. Prostsze:
CREATE INDEX name_idx ON table (text_col)
WHERE text_col IS NOT NULL;
Pamiętaj, aby uruchomić ANALYZE table
po utworzeniu indeksu. (Autovacuum robi to automatycznie po pewnym czasie, jeśli nie zrobisz tego ręcznie, ale jeśli testujesz zaraz po utworzeniu, test zakończy się niepowodzeniem.)
Następnie, aby przekonać planistę zapytań, że można użyć określonego indeksu częściowego, powtórz polecenie WHERE
warunek w zapytaniu - nawet jeśli wydaje się całkowicie zbędny:
SELECT col1,col2, .. colN
FROM table
WHERE text_col = 'my_value'
AND text_col IS NOT NULL; -- repeat condition
Voila.
Zgodnie z dokumentacją:
Należy jednak pamiętać, że predykat musi odpowiadać warunkom użytym w zapytaniach, które mają korzystać z indeksu. Aby być precyzyjnym, częściowy indeks może być użyty w zapytaniu tylko wtedy, gdy system rozpozna, że WHERE
warunek zapytania matematycznie implikuje predykat indeksu. PostgreSQL nie posiada wyrafinowanego narzędzia do dowodzenia twierdzeń, które potrafi rozpoznać matematycznie równoważne wyrażenia zapisane w różnych formach. (Takie ogólne twierdzenie jest nie tylko niezwykle trudne do stworzenia, ale prawdopodobnie byłoby zbyt wolne, aby miało jakikolwiek rzeczywisty użytek.) System może rozpoznać proste implikacje nierówności, na przykład „x <1” implikuje „x <2”; w przeciwnym razie orzeczenie warunek musi dokładnie odpowiadać części zapytania WHERE
warunek lub indeks nie zostanie rozpoznany jako nadający się do użytku. Dopasowywanie odbywa się w czasie planowania zapytania, a nie w czasie wykonywania. W rezultacie sparametryzowane klauzule zapytań nie działają z indeksem częściowym.
Co do zapytań parametrycznych:ponownie dodaj (redundantny) predykat indeksu częściowego jako dodatkowy, stały WHERE
stan i działa dobrze.
Ważna aktualizacja w Postgresie 9.6 znacznie zwiększa szanse na skanowanie tylko z indeksem (co może sprawić, że zapytania będą tańsze, a planista zapytań będzie chętniej wybierał takie plany zapytań). Powiązane:
- PostgreSQL nie używa indeksu podczas count(*)