sql >> Databáze >  >> RDS >> PostgreSQL

Znovu použijte vypočítanou hodnotu výběru

Č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í.




  1. Vnořený dotaz SQL pomalý pomocí IN

  2. Jak deklarovat uživatelsky definovat výjimku pomocí PRAGMA EXCEPTION_INIT

  3. MySQL Aktualizace více řádků v jednom sloupci na základě hodnot ze stejného sloupce

  4. Nerozlišují názvy funkcí v PostgreSQL velká a malá písmena?