Tempo di prova
Non vedi la valutazione delle singole funzioni per riga in EXPLAIN
produzione.
Prova con EXPLAIN ANALYZE
per ottenere i tempi di query effettivi per confrontare l'efficacia complessiva. Esegui un paio di volte per escludere gli artefatti di memorizzazione nella cache. Per query semplici come questa, ottieni numeri più affidabili per il runtime totale con:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Richiede Postgres 9.2+ . Per documentazione :
Evita valutazioni ripetute
Normalmente, le espressioni in una sottoquery vengono valutate una volta . Ma Postgres può comprimere subquery banali se pensa che sarà più veloce.
Per introdurre una barriera di ottimizzazione, puoi utilizzare un CTE
invece della sottoquery. Questo garantisce che Postgres calcola ST_SnapToGrid(geom, 50)
una sola volta:
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
Tuttavia, questo è probabilmente più lento rispetto a una sottoquery a causa di un sovraccarico maggiore per un CTE. La chiamata di funzione è probabilmente molto economica. In generale, Postgres sa meglio come ottimizzare un piano di query. Introduci una tale barriera di ottimizzazione solo se ne sai di più.
Semplifica
Ho cambiato il nome del punto calcolato nella sottoquery/CTE in geom1
per chiarire è diverso dal geom
originale . Questo aiuta a chiarire il più importante cosa qui:
GROUP BY geom1
invece di:
GROUP BY x, y
Ovviamente è più economico e può influire sul fatto che la chiamata di funzione venga ripetuta. Quindi, questo è probabilmente il più veloce:
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 forse questo:
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;
Prova tutti e tre con EXPLAIN ANALYZE
o EXPLAIN (ANALYZE, TIMING OFF)
e vedere di persona. Testare>> indovinare.