Tempo de teste
Você não vê a avaliação de funções individuais por linha no
EXPLAIN
resultado. Teste com
EXPLAIN ANALYZE
para obter tempos de consulta reais para comparar a eficácia geral. Execute algumas vezes para descartar artefatos de armazenamento em cache. Para consultas simples como essa, você obtém números mais confiáveis para o tempo de execução total com:EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Requer Postgres 9.2+ . Por documentação :
Evitar avaliações repetidas
Normalmente, as expressões em uma subconsulta são avaliadas uma vez . Mas o Postgres pode recolher subconsultas triviais se achar que isso será mais rápido.
Para introduzir uma barreira de otimização, você pode usar um CTE em vez da subconsulta. Isso garantia que o Postgres calcula
ST_SnapToGrid(geom, 50)
apenas uma vez: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
No entanto, isso é provavelmente mais lento do que uma subconsulta devido a mais sobrecarga para um CTE. A chamada de função é provavelmente muito barata. Geralmente, o Postgres sabe melhor como otimizar um plano de consulta. Só introduza essa barreira de otimização se você souber melhor.
Simplifique
Alterei o nome do ponto computado na subconsulta/CTE para
geom1
para esclarecer que é diferente do geom
original . Isso ajuda a esclarecer o mais importante coisa aqui:GROUP BY geom1
ao invés de:
GROUP BY x, y
Isso é obviamente mais barato - e pode influenciar se a chamada da função é repetida. Então, isso é provavelmente mais rápido:
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!
Ou talvez isso:
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;
Teste todos os três com
EXPLAIN ANALYZE
ou EXPLAIN (ANALYZE, TIMING OFF)
e veja por si mesmo. Testando>> adivinhando.