PostgreSQL: COUNT (*) używa skanowania sekwencyjnego, a nie indeksu

12

Dlaczego PostgreSQL sekwencyjnie skanuje tabelę w poszukiwaniu COUNT(*)zapytań, podczas gdy istnieje bardzo mały i indeksowany klucz podstawowy?

Adam Matan
źródło

Odpowiedzi:

16

Na oficjalnych stronach wiki dać odpowiedź, że:

[...] Powód, dla którego jest to powolny, jest związany z implementacją MVCC w PostgreSQL. Fakt, że wiele transakcji widzi różne stany danych, oznacza, że ​​„COUNT (*)” nie może mieć prostego sposobu na podsumowanie danych w całej tabeli; PostgreSQL musi w pewnym sensie przejść przez wszystkie wiersze. Zwykle powoduje to odczyt sekwencyjnego skanu informacji o każdym wierszu w tabeli. [...]

Ponadto można wypróbować ANALIZĘ, aby odbudować informacje dla narzędzia do planowania zapytań.

Powinieneś uzyskać lepszą wydajność, COUNT(an uniquly indexed field)ale jeśli jest to bardzo duże, skanowanie sekwencyjne jest jedynym sposobem, aby to zrobić.

Jeśli potrzebujesz bardzo szybkich numerów i nie boisz się zapytać o schemat, możesz wykonać następujące czynności

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

Ale nie polegaj na tych wartościach, ponieważ jest to tylko „szacunkowa” (choć często dokładna) liczba krotek w tabeli.

DrColossos
źródło
Nie sądzę, żeby to było poprawne. Nigdzie nie czytałem, gdzie COUNT(pk)poprawi się wydajność. Myślę, że zawsze wykona skan
sekwencyjny
1
Bez poprawnej klauzuli where zostanie wykonane skanowanie sekwencji. Przy dostatecznym wyborze klauzuli, gdzie postgresql MOŻE użyć indeksu, ale pamiętaj, że Wrócę do tabeli, aby sprawdzić widoczność krotek, które zgłasza.
Scott Marlowe,
Innym sposobem na uzyskanie szacunkowej liczby wierszy, które uważam za łatwiejsze do zapamiętania, jest EXPLAIN SELECT * from your_table;. Nie spowoduje to wykonania zapytania. Dane wyjściowe obejmują rows=…szacunkową liczbę wierszy.
Sven Marnach