sql >> Database >  >> RDS >> PostgreSQL

Berekende geselecteerde waarde opnieuw gebruiken

Testtiming

U ziet de evaluatie van individuele functies per rij niet in de EXPLAIN uitvoer.

Test met EXPLAIN ANALYZE om werkelijke querytijden te krijgen om de algehele effectiviteit te vergelijken. Voer een paar keer uit om caching-artefacten uit te sluiten. Voor eenvoudige vragen zoals deze krijgt u betrouwbaardere cijfers voor de totale looptijd met:

EXPLAIN (ANALYZE, TIMING OFF) SELECT ...

Vereist Postgres 9.2+ . Per documentatie :

Voorkom herhaalde evaluatie

Normaal gesproken worden expressies in een subquery eenmaal geëvalueerd . Maar Postgres kan triviale subquery's samenvouwen als het denkt dat dat sneller zal zijn.

Om een ​​optimalisatiebarrière te introduceren, kunt u een CTE in plaats van de subquery. Dit garandeert dat Postgres ST_SnapToGrid(geom, 50) . berekent eenmalig:

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

Dit is echter waarschijnlijk langzamer dan een subquery vanwege meer overhead voor een CTE. De functieaanroep is waarschijnlijk erg goedkoop. Over het algemeen weet Postgres beter hoe een queryplan te optimaliseren. Introduceer zo'n optimalisatiebarrière alleen als je beter weet.

Vereenvoudig

Ik heb de naam van het berekende punt in de subquery / CTE gewijzigd in geom1 om te verduidelijken dat het anders is dan de originele geom . Dat helpt om de belangrijkste . te verduidelijken ding hier:

GROUP BY geom1

in plaats van:

GROUP BY x, y

Dat is uiteraard goedkoper - en kan van invloed zijn op het al dan niet herhalen van de functieaanroep. Dit is dus waarschijnlijk het snelst:

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!

Of misschien dit:

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 ze alle drie met EXPLAIN ANALYZE of EXPLAIN (ANALYZE, TIMING OFF) en zie het zelf. Testen>> gissen.




  1. Hoe parallelle plannen opstarten - Deel 5

  2. Het resetten van AUTO_INCREMENT duurt lang in MySQL

  3. Doe WHERE ID IN met een subquery die een reeks ID's retourneert

  4. Wat is de opgeslagen procedure en waarom de opgeslagen procedure?