Как оптимизировать запрос SELECT COUNT?
SELECT COUNT(*) FROM - перебрать все строки.SELECT COUNT(id) FROM - перебрать все строки, в которых указанное поле (в данном случае id) имеет значение отличное от NULL.
Без указания полей - наиболее оптимальный вариант для PostgreSQL:SELECT COUNT(*) FROM table WHERE field = value
https://wiki.postgresql.org/wiki/Slow_Counting
Если все совсем плохо, то как вариант, можно сделать собственный счетчик.
Вот вырезка из PostgreSQL Wiki на русском языке:Почему "SELECT count(*) FROM bigtable;" работает медленно?
Потому что не используется индекс. PostgreSQL выполняет проверку видимости каждой записи и таким образом производит последовательное сканирование всей таблицы. Если вы хотите, вы можете отслеживать количество строк в таблице с помощью триггеров, но это вызовет замедление при операциях записи в таблицу.
Вы можете получить некоторую оценку. Колонка reltuples в таблице pg_class содержит информацию из результата выполнения последнего оператора ANALYZE на эту таблицу. На большой таблице, точность этого значения составляет тысячные доли процента, что вполне достаточно для многих целей.
"Точный" результат count, часто не будет точным долгое время в любом случае; из-за конкурентности MVCC, count будет точным только на момент вызова запущенного запроса SELECT count(*) (или ограничиваться уровнями изоляции транзакций данной транзакции), и может потерять актуальность уже в момент завершения запроса. При постоянной работе транзакций, изменяющий таблицу, два вызова count(*), которые завершатся в одно и то же время могут показать разные значения, если изменяющая транзакция завершилась между их вызовами.
https://wiki.postgresql.org/wiki/Часто_Задаваемые_...
Есть хак. Очень быстрый, но слегка неточный.SELECT reltuples FROM pg_class WHERE oid = 'schema_name.table_name'::regclass;
Например, в таблице с 31560 строками он только что выдал мне цифру 31558, но выполнялся в 20 раз быстрее. Точность зависит от того, на сколько часто запускается для таблицы ANALYZE.