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.