Časování testu
V EXPLAIN
nevidíte vyhodnocení jednotlivých funkcí na řádek výstup.
Otestujte pomocí EXPLAIN ANALYZE
získat skutečné časy dotazů pro porovnání celkové efektivity. Spusťte několikrát, abyste vyloučili artefakty z ukládání do mezipaměti. Pro jednoduché dotazy, jako je tento, získáte spolehlivější čísla pro celkovou dobu běhu pomocí:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Vyžaduje Postgres 9.2+ . Podle dokumentace :
Zabránit opakovanému hodnocení
Normálně jsou výrazy v poddotazu vyhodnoceny jednou . Ale Postgres může sbalit triviální poddotazy, pokud si myslí, že to bude rychlejší.
Chcete-li zavést optimalizační bariéru, můžete použít CTE
místo poddotazu. To zaručuje že Postgres počítá ST_SnapToGrid(geom, 50)
pouze jednou:
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
Toto je však pravděpodobně pomalejší než poddotaz kvůli větší režii pro CTE. Volání funkce je pravděpodobně velmi levné. Postgres obecně ví lépe, jak optimalizovat plán dotazů. Takovou optimalizační bariéru zavádějte, pouze pokud víte lépe.
Zjednodušit
Změnil jsem název počítaného bodu v poddotazu / CTE na geom1
pro objasnění se liší od původního geom
. To pomáhá vyjasnit to důležitější něco tady:
GROUP BY geom1
místo:
GROUP BY x, y
To je samozřejmě levnější – a může to mít vliv na to, zda se bude volání funkce opakovat. Takže toto je pravděpodobně nejrychlejší:
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!
Nebo možná toto:
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;
Otestujte všechny tři pomocí EXPLAIN ANALYZE
nebo EXPLAIN (ANALYZE, TIMING OFF)
a přesvědčte se sami. Testování>> hádání.