Czas testu
Nie widzisz oceny poszczególnych funkcji na wiersz w EXPLAIN
wyjście.
Przetestuj za pomocą EXPLAIN ANALYZE
aby uzyskać rzeczywiste czasy zapytań w celu porównania ogólnej efektywności. Uruchom kilka razy, aby wykluczyć artefakty buforowania. W przypadku prostych zapytań, takich jak to, uzyskasz bardziej wiarygodne liczby dotyczące całkowitego czasu działania dzięki:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Wymaga Postgresa 9.2+ . Według dokumentacji :
Zapobiegaj powtórnej ocenie
Zwykle wyrażenia w podzapytaniu są oceniane raz . Ale Postgres może zwijać trywialne podzapytania, jeśli uzna, że będzie to szybsze.
Aby wprowadzić barierę optymalizacji, możesz użyć CTE
zamiast podzapytania. To gwarancje że Postgres oblicza ST_SnapToGrid(geom, 50)
tylko raz:
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
Jednak prawdopodobnie jest wolniej niż podzapytanie ze względu na większe obciążenie dla CTE. Wywołanie funkcji jest prawdopodobnie bardzo tanie. Generalnie Postgres wie lepiej, jak zoptymalizować plan zapytań. Wprowadzaj taką barierę optymalizacji tylko wtedy, gdy wiesz lepiej.
Uprość
Zmieniłem nazwę obliczonego punktu w podzapytaniu / CTE na geom1
aby wyjaśnić, że różni się od oryginalnego geom
. To pomaga wyjaśnić ważniejsze rzecz tutaj:
GROUP BY geom1
zamiast:
GROUP BY x, y
Jest to oczywiście tańsze - i może mieć wpływ na to, czy wywołanie funkcji zostanie powtórzone. Tak więc jest to prawdopodobnie najszybsze:
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!
A może to:
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;
Przetestuj wszystkie trzy za pomocą EXPLAIN ANALYZE
lub EXPLAIN (ANALYZE, TIMING OFF)
i przekonaj się sam. Testowanie>> zgadywanie.