Време на теста
Не виждате оценката на отделните функции на ред в EXPLAIN
изход.
Тествайте с EXPLAIN ANALYZE
за да получите действително време за заявка, за да сравните общата ефективност. Стартирайте няколко пъти, за да изключите кеширащи артефакти. За прости заявки като тази получавате по-надеждни числа за общото време на изпълнение с:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Изисква Postgres 9.2+ . По документация :
Предотвратяване на повторна оценка
Обикновено изразите в подзаявка се оценяват веднъж . Но Postgres може да свие тривиални подзаявки, ако смята, че това ще бъде по-бързо.
За да въведете бариера за оптимизиране, можете да използвате CTEсилен>
вместо подзаявката. Това гаранции че Postgres изчислява ST_SnapToGrid(geom, 50)
само веднъж:
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
Това обаче вероятно е по-бавно отколкото подзаявка поради повече режийни разходи за CTE. Извикването на функцията вероятно е много евтино. Като цяло Postgres знае по-добре как да оптимизира план за заявка. Въведете такава бариера за оптимизиране само ако знаете по-добре.
Опростяване
Промених името на изчислената точка в подзаявката / CTE на geom1
за да поясня, че е различен от оригиналния geom
. Това помага да се изясни по-важното нещо тук:
GROUP BY geom1
вместо:
GROUP BY x, y
Това очевидно е по-евтино - и може да окаже влияние върху това дали извикването на функцията се повтаря. Така че това вероятно е най-бързото:
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!
Или може би това:
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;
Тествайте и трите с EXPLAIN ANALYZE
или EXPLAIN (ANALYZE, TIMING OFF)
и вижте сами. Тестване>> отгатване.