PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Melhor maneira de obter a contagem de resultados antes da aplicação de LIMIT

SQL puro


As coisas mudaram desde 2008. Você pode usar uma função de janela para obter a contagem completa e o resultado limitado em uma consulta. Introduzido com o PostgreSQL 8.4 em 2009.
SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

Observe que isso pode ser consideravelmente mais caro do que sem a contagem total . Todas as linhas precisam ser contadas, e um possível atalho pegando apenas as linhas superiores de um índice correspondente pode não ser mais útil.
Não importa muito com tabelas pequenas ou full_count <=OFFSET + LIMIT . Importa para um full_count substancialmente maior .

Caixa de canto :quando OFFSET é pelo menos tão grande quanto o número de linhas da consulta base, nenhuma linha é devolvido. Portanto, você também não recebe full_count . Possível alternativa:
  • Execute uma consulta com um LIMIT/OFFSET e também obtenha o número total de linhas

Sequência de eventos em um SELECT consulta


( 0. CTEs são avaliados e materializados separadamente. No Postgres 12 ou posterior o planejador pode inline aqueles como subconsultas antes de ir trabalhar.) Não aqui.
  1. WHERE cláusula (e JOIN condições, embora nenhuma em seu exemplo) filtre as linhas qualificadas da(s) tabela(s) base. O restante é baseado no subconjunto filtrado.

( 2. GROUP BY e funções agregadas iriam aqui.) Não aqui.

( 3. Outro SELECT expressões de lista são avaliadas com base em colunas agrupadas/agregadas.) Não aqui.

  1. As funções da janela são aplicadas dependendo do OVER cláusula e a especificação do quadro da função. O simples count(*) OVER() é baseado em todas as linhas de qualificação.

  2. ORDER BY

( 6. DISTINCT ou DISTINCT ON iria aqui.) Não aqui.
  1. LIMIT / OFFSET são aplicados com base na ordem estabelecida para selecionar as linhas a serem retornadas.

LIMIT / OFFSET torna-se cada vez mais ineficiente com um número crescente de linhas na tabela. Considere abordagens alternativas se precisar de melhor desempenho:
  • Otimize a consulta com OFFSET em uma tabela grande

Alternativas para obter a contagem final


Existem abordagens completamente diferentes para obter a contagem de linhas afetadas (não a contagem completa antes de OFFSET &LIMIT foram aplicados). O Postgres tem uma contabilidade interna de quantas linhas foram afetadas pelo último comando SQL. Alguns clientes podem acessar essas informações ou contar as próprias linhas (como o psql).

Por exemplo, você pode recuperar o número de linhas afetadas em plpgsql imediatamente após executar um comando SQL com:
GET DIAGNOSTICS integer_var = ROW_COUNT;

Detalhes no manual.

Ou você pode usar pg_num_rows em PHP . Ou funções semelhantes em outros clientes.

Relacionado:
  • Calcule o número de linhas afetadas pela consulta em lote no PostgreSQL