PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Riutilizza il valore selezionato calcolato

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.