PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Berechneten Auswahlwert wiederverwenden

Timing testen

Die Auswertung einzelner Funktionen pro Zeile sehen Sie im EXPLAIN nicht Ausgang.

Testen Sie mit EXPLAIN ANALYZE um die tatsächlichen Abfragezeiten zu erhalten, um die Gesamteffektivität zu vergleichen. Führen Sie ein paar Mal aus, um Caching-Artefakte auszuschließen. Für einfache Abfragen wie diese erhält man verlässlichere Zahlen für die Gesamtlaufzeit mit:

EXPLAIN (ANALYZE, TIMING OFF) SELECT ...

Erfordert Postgres 9.2+ . Pro Dokumentation :

Wiederholte Bewertung verhindern

Normalerweise werden Ausdrücke in einer Unterabfrage einmal ausgewertet . Aber Postgres kann triviale Unterabfragen zusammenklappen, wenn es der Meinung ist, dass dies schneller geht.

Um eine Optimierungsbarriere einzuführen, könnten Sie einen CTE anstelle der Unterabfrage. Dies garantiert dass Postgres ST_SnapToGrid(geom, 50) berechnet einmalig:

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

Dies ist jedoch wahrscheinlich langsamer als eine Unterabfrage aufgrund des höheren Aufwands für einen CTE. Der Funktionsaufruf ist wahrscheinlich sehr billig. Im Allgemeinen weiß Postgres besser, wie man einen Abfrageplan optimiert. Führen Sie eine solche Optimierungsbarriere nur ein, wenn Sie es besser wissen.

Vereinfachen

Ich habe den Namen des berechneten Punktes in der Unterabfrage / CTE in geom1 geändert Zur Verdeutlichung unterscheidet es sich vom ursprünglichen geom . Das hilft, das Wichtigere zu klären Sache hier:

GROUP BY geom1

statt:

GROUP BY x, y

Das ist offensichtlich billiger - und kann einen Einfluss darauf haben, ob der Funktionsaufruf wiederholt wird. Das ist also wahrscheinlich am schnellsten:

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!

Oder vielleicht so:

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;

Testen Sie alle drei mit EXPLAIN ANALYZE oder EXPLAIN (ANALYZE, TIMING OFF) und sehen Sie selbst. Testen>> erraten.