PostgreSQL: COUNT (*) использует последовательное сканирование, а не индекс

12

Почему PostgreSQL последовательно сканирует таблицу для COUNT(*)запроса, в то время как существует очень маленький и проиндексированный первичный ключ?

Адам Матан
источник

Ответы:

15

На официальных страницах вики дать ответ на этот вопрос :

[...] Причина, по которой это происходит медленно, связана с реализацией MVCC в PostgreSQL. Тот факт, что несколько транзакций могут видеть разные состояния данных, означает, что не может быть прямого способа для COUNT (*) суммировать данные по всей таблице; PostgreSQL должен пройти через все строки, в некотором смысле. Обычно это приводит к последовательному сканированию, считывающему информацию о каждой строке таблицы. [...]

Кроме того, вы можете попробовать ANALYZE перестроить информацию для планировщика запросов.

Вы должны получить более высокую производительность при использовании, COUNT(an uniquly indexed field)но если она очень велика, единственный способ сделать это - сканирование seq.

Если вам нужны очень быстрые цифры и вы не боитесь запрашивать схему, вы можете сделать следующее

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

Но не полагайтесь на эти значения, так как это только «приблизительное» (хотя часто точное) число кортежей в таблице.

DrColossos
источник
Я не думаю, что это правильно. Я нигде ничего не читал, где COUNT(pk)улучшу производительность. Я думаю, что он всегда будет делать seq-scan
vol7ron
1
Без правильного предложения where будет выполняться сканирование seq. При достаточном выборе пункта postgresql МОЖЕТ использовать индекс, но имейте в виду, что он вернется к таблице, чтобы проверить видимость кортежей, о которых он сообщает.
Скотт Марлоу