sql >> Base de Datos >  >> RDS >> PostgreSQL

La mejor manera de obtener el recuento de resultados antes de aplicar LIMIT

SQL puro

Las cosas han cambiado desde 2008. Puede usar una función de ventana para obtener el recuento completo y el resultado limitado en una consulta. Introducido con PostgreSQL 8.4 en 2009.

SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

Tenga en cuenta que esto puede ser considerablemente más caro que sin el recuento total . Se deben contar todas las filas, y un posible atajo que toma solo las filas superiores de un índice coincidente ya no será útil.
No importa mucho con tablas pequeñas o full_count <=OFFSET + LIMIT . Importa para un full_count sustancialmente mayor .

Estuche de esquina :cuando OFFSET es al menos tan grande como el número de filas de la consulta base, ninguna fila es regresado. Entonces tampoco obtienes full_count . Posible alternativa:

  • Ejecute una consulta con LIMIT/OFFSET y también obtenga el número total de filas

Secuencia de eventos en un SELECT consulta

( 0. Los CTE se evalúan y materializan por separado. En Postgres 12 o posterior, el planificador puede incluirlos como subconsultas antes de comenzar a trabajar). Aquí no.

  1. WHERE cláusula (y JOIN condiciones, aunque ninguna en su ejemplo) filtre las filas de calificación de la (s) tabla (s) base (s). El resto se basa en el subconjunto filtrado.

( 2. GROUP BY y las funciones agregadas irían aquí.) Aquí no.

( 3. Otro SELECT las expresiones de lista se evalúan en función de columnas agrupadas/agregadas). No aquí.

  1. Las funciones de ventana se aplican dependiendo de OVER cláusula y la especificación del marco de la función. El simple count(*) OVER() se basa en todas las filas que califican.

  2. ORDER BY

( 6. DISTINCT o DISTINCT ON iría aquí.) No aquí.

  1. LIMIT / OFFSET se aplican según el orden establecido para seleccionar filas para devolver.

LIMIT / OFFSET se vuelve cada vez más ineficiente con un número creciente de filas en la tabla. Considere enfoques alternativos si necesita un mejor rendimiento:

  • Optimizar consulta con OFFSET en tabla grande

Alternativas para obtener el conteo final

Existen enfoques completamente diferentes para obtener el recuento de filas afectadas (no la cuenta completa antes de OFFSET &LIMIT se aplicaron). Postgres tiene contabilidad interna sobre cuántas filas se vieron afectadas por el último comando SQL. Algunos clientes pueden acceder a esa información o contar filas ellos mismos (como psql).

Por ejemplo, puede recuperar el número de filas afectadas en plpgsql inmediatamente después de ejecutar un comando SQL con:

GET DIAGNOSTICS integer_var = ROW_COUNT;

Detalles en el manual.

O puede usar pg_num_rows en PHP . O funciones similares en otros clientes.

Relacionado:

  • Calcular el número de filas afectadas por la consulta por lotes en PostgreSQL