Чистый SQL
С 2008 года все изменилось. Вы можете использовать оконную функцию , чтобы получить полный счет и ограниченный результат в одном запросе. (Введено в PostgreSQL 8.4 в 2009 ).
SELECT foo
, count(*) OVER() AS full_count
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>
Обратите внимание, что это может быть значительно дороже, чем без общего количества. Все строки должны быть подсчитаны, и возможный ярлык, извлекающий только верхние строки из соответствующего индекса, может больше не помогать.
Не имеет большого значения для небольших таблиц или full_count
<= <code>OFFSET + LIMIT
. Вопросы для значительно большего full_count
.
Угловой регистр : когда OFFSET
не меньше, чем количество строк из базового запроса, без строки возвращается. Таким образом, вы также не получите full_count
. Возможная альтернатива:
Рассмотрим последовательность событий :
WHERE
предложение (и JOIN
условия, но не здесь) фильтруют строки квалификации из базовой таблицы (таблиц).
(GROUP BY
и агрегатные функции будут здесь.)
Оконные функции применяются с учетом всех подходящих строк (в зависимости от предложения OVER
и спецификации фрейма функции). Простое count(*) OVER()
основано на всех строках.
ORDER BY
(DISTINCT
или DISTINCT ON
пошли бы сюда.)
LIMIT
/ OFFSET
применяются на основе установленного порядка выбора строк для возврата.
LIMIT
/ OFFSET
становится все более неэффективным с ростом числа строк в таблице. Рассмотрите альтернативные подходы, если вам нужна лучшая производительность:
Альтернативы, чтобы получить окончательный счет
Существуют совершенно разные подходы, чтобы получить количество затронутых строк ( не полный счет до применения OFFSET
& LIMIT
). Postgres имеет внутреннюю учетную запись о количестве строк, затронутых последней командой SQL. Некоторые клиенты могут получить доступ к этой информации или сами считать строки (например, psql).
Например, вы можете получить количество затронутых строк в plpgsql сразу после выполнения команды SQL с помощью:
GET DIAGNOSTICS integer_var = ROW_COUNT;
Подробности в руководстве.
Или вы можете использовать pg_num_rows
в PHP . Или аналогичные функции в других клиентах.
Связанный: