Testtid
Du ser inte utvärderingen av enskilda funktioner per rad i EXPLAIN
produktion.
Testa med EXPLAIN ANALYZE
för att få faktiska frågetider för att jämföra den totala effektiviteten. Kör ett par gånger för att utesluta cacheartefakter. För enkla frågor som denna får du mer tillförlitliga siffror för den totala körtiden med:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Kräver Postgres 9.2+ . Per dokumentation :
Förhindra upprepad utvärdering
Normalt utvärderas uttryck i en underfråga en gång . Men Postgres kan kollapsa triviala underfrågor om den tror att det kommer att gå snabbare.
För att införa en optimeringsbarriär kan du använda en CTE
istället för underfrågan. Detta garanti att Postgres beräknar ST_SnapToGrid(geom, 50)
endast en gång:
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
Men det här är förmodligen långsammare än en underfråga på grund av mer overhead för en CTE. Funktionsanropet är förmodligen väldigt billigt. I allmänhet vet Postgres bättre hur man optimerar en frågeplan. Inför bara en sådan optimeringsbarriär om du vet bättre.
Förenkla
Jag ändrade namnet på den beräknade punkten i underfrågan / CTE till geom1
för att förtydliga att den skiljer sig från den ursprungliga geom
. Det hjälper till att förtydliga det viktigare sak här:
GROUP BY geom1
istället för:
GROUP BY x, y
Det är så klart billigare – och kan ha inflytande på om funktionsanropet upprepas. Så det här är förmodligen snabbast:
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!
Eller kanske detta:
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;
Testa alla tre med EXPLAIN ANALYZE
eller EXPLAIN (ANALYZE, TIMING OFF)
och se själv. Testar>> gissning.