Testtid
Du kan ikke se evalueringen af individuelle funktioner pr. række i EXPLAIN
produktion.
Test med EXPLAIN ANALYZE
for at få faktiske forespørgselstider for at sammenligne den samlede effektivitet. Kør et par gange for at udelukke caching-artefakter. For simple forespørgsler som denne får du mere pålidelige tal for den samlede kørselstid med:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Kræver Postgres 9.2+ . Pr. dokumentation :
Undgå gentagen evaluering
Normalt evalueres udtryk i en underforespørgsel én gang . Men Postgres kan kollapse trivielle underforespørgsler, hvis det tror, det vil være hurtigere.
For at indføre en optimeringsbarriere kan du bruge en CTE
i stedet for underforespørgslen. Dette garanti at Postgres beregner ST_SnapToGrid(geom, 50)
kun én gang:
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
Dette er dog sandsynligvis langsommere end en underforespørgsel på grund af mere overhead for en CTE. Funktionsopkaldet er nok meget billigt. Generelt ved Postgres bedre, hvordan man optimerer en forespørgselsplan. Indfør kun en sådan optimeringsbarriere, hvis du ved bedre.
Forenkle
Jeg ændrede navnet på det beregnede punkt i underforespørgslen / CTE til geom1
for at tydeliggøre, at den er forskellig fra den originale geom
. Det hjælper med at tydeliggøre det vigtigere ting her:
GROUP BY geom1
i stedet for:
GROUP BY x, y
Det er naturligvis billigere – og kan have indflydelse på, om funktionskaldet gentages. Så dette er nok hurtigst:
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 måske denne:
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;
Test alle tre med EXPLAIN ANALYZE
eller EXPLAIN (ANALYZE, TIMING OFF)
og se selv. Tester>> gætte.