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

Reutilizar el valor seleccionado calculado

Tiempo de prueba

No ve la evaluación de funciones individuales por fila en EXPLAIN producción.

Prueba con EXPLAIN ANALYZE para obtener tiempos de consulta reales para comparar la efectividad general. Ejecute un par de veces para descartar artefactos de almacenamiento en caché. Para consultas simples como esta, obtiene números más confiables para el tiempo de ejecución total con:

EXPLAIN (ANALYZE, TIMING OFF) SELECT ...

Requiere Postgres 9.2+ . Según documentación :

Evitar la evaluación repetida

Normalmente, las expresiones en una subconsulta se evalúan una vez . Pero Postgres puede colapsar subconsultas triviales si cree que será más rápido.

Para introducir una barrera de optimización, puede usar un CTE en lugar de la subconsulta. Esto garantiza que Postgres calcula ST_SnapToGrid(geom, 50) una sola vez:

WITH cte AS (
   SELECT ST_SnapToGrid(geom, 50) AS geom1
   FROM   points
   )
SELECT COUNT(*)   AS n
     , ST_X(geom1) AS x
     , ST_Y(geom1) AS y
FROM   cte
GROUP  BY geom1;         -- see below

Sin embargo, esto es probablemente más lento que una subconsulta debido a una mayor sobrecarga para un CTE. La llamada a la función es probablemente muy barata. En general, Postgres sabe mejor cómo optimizar un plan de consulta. Solo introduzca una barrera de optimización de este tipo si sabe mejor.

Simplificar

Cambié el nombre del punto calculado en la subconsulta/CTE a geom1 para aclarar que es diferente del geom original . Eso ayuda a aclarar lo más importante cosa aquí:

GROUP BY geom1

en lugar de:

GROUP BY x, y

Obviamente, eso es más barato, y puede influir en si la llamada a la función se repite. Entonces, este es probablemente el más rápido:

SELECT COUNT(*) AS n
     , ST_X(ST_SnapToGrid(geom, 50)) AS x
     , ST_y(ST_SnapToGrid(geom, 50)) AS y
FROM   points
GROUP  BY ST_SnapToGrid(geom, 50);         -- same here!

O tal vez esto:

SELECT COUNT(*)    AS n
     , ST_X(geom1) AS x
     , ST_y(geom1) AS y
FROM (
   SELECT ST_SnapToGrid(geom, 50) AS geom1
   FROM   points
   ) AS tmp
GROUP  BY geom1;

Pruebe los tres con EXPLAIN ANALYZE o EXPLAIN (ANALYZE, TIMING OFF) y ver por ti mismo. Probando>> adivinando.