[PT] Otimizar consultas PostGIS: guia prático para melhorar o desempenho


Bases de dados espaciais podem conter milhões de objetos geográficos. Em alguns casos, uma consulta PostGIS pode levar vários segundos — ou até vários minutos.

Esse problema geralmente acontece quando:

  • os índices espaciais não são utilizados
  • as geometrias são complexas
  • as consultas espaciais estão mal construídas
  • ou as estatísticas da base de dados não estão atualizadas.

Neste artigo, veremos as etapas clássicas para diagnosticar e otimizar uma consulta PostGIS lenta.


1. Começar analisando a consulta

O primeiro passo consiste em compreender como o PostgreSQL executa a consulta.

Para isso, utiliza-se:

EXPLAIN ANALYZE

Exemplo:

EXPLAIN ANALYZE
SELECT *
FROM routes r
JOIN communes c
ON ST_Intersects(r.geom, c.geom);

Esse comando permite verificar:

  • se um índice espacial está sendo utilizado
  • quantas linhas são analisadas
  • quanto tempo leva cada etapa.

Se aparecer:

Seq Scan

isso significa que o PostgreSQL está percorrendo toda a tabela.


2. Verificar a presença de índices espaciais

Os índices são essenciais para consultas espaciais.

Um índice espacial normalmente é criado assim:

CREATE INDEX idx_routes_geom
ON routes
USING GIST (geom);

Os índices permitem que o PostgreSQL reduza drasticamente o número de geometrias analisadas.

Sem um índice espacial, o desempenho pode ser desastroso.


3. Utilizar operadores espaciais compatíveis com índices

Algumas funções do PostGIS utilizam automaticamente os índices espaciais.

Por exemplo:

No entanto, muitas vezes é útil adicionar um filtro de bounding box:

geom && other_geom

Exemplo:

SELECT *
FROM routes r
JOIN communes c
ON r.geom && c.geom
AND ST_Intersects(r.geom, c.geom);

O teste de bounding box é muito mais rápido.


4. Verificar a complexidade das geometrias

Geometrias muito detalhadas podem tornar algumas operações significativamente mais lentas.

Em alguns casos, pode ser útil simplificar as geometrias:

ST_Simplify(geom, tolerance)

ou criar uma tabela simplificada para determinadas análises.


5. Evitar certas funções nas cláusulas WHERE

Algumas funções impedem o uso eficiente dos índices.

Por exemplo:

ST_Buffer(geom, 100)

em uma cláusula WHERE pode tornar a consulta muito lenta.

Exemplo ruim:

WHERE ST_Intersects(ST_Buffer(geom,100), zone)

Muitas vezes é melhor reformular a consulta.


6. Verificar as estatísticas da base de dados

O PostgreSQL utiliza estatísticas para escolher o plano de execução.

Após muitas modificações nos dados, recomenda-se executar:

ANALYZE

ou

VACUUM ANALYZE

Isso ajuda a melhorar o plano de consulta.


7. Limitar os dados analisados

Frequentemente é útil reduzir o volume de dados antes das operações espaciais.

Por exemplo, utilizando um filtro por atributo:

WHERE type = ‘rodovia’

Isso reduz o número de objetos analisados.


8. Testar diferentes abordagens

Em alguns casos, diferentes formas de escrever a consulta podem produzir desempenhos muito diferentes.

Por isso, é útil testar diferentes estratégias:

  • junção espacial
  • subconsulta
  • materialização intermediária.

9. Os 5 erros mais comuns no PostGIS que deixam uma consulta lenta

Alguns erros aparecem com muita frequência em bases de dados espaciais.

Ausência de índice espacial

Essa é a causa mais comum.

Sem índice espacial, o PostgreSQL precisa analisar todas as geometrias da tabela.

Criar um índice:

CREATE INDEX idx_routes_geom
ON routes
USING GIST (geom);


Ordem incorreta das operações

Algumas consultas executam diretamente uma operação espacial custosa em toda a tabela.

Exemplo ineficiente:

SELECT *
FROM edificios
WHERE ST_Intersects(geom, ST_Buffer(:zone,100));

Nesse caso, a função ST_Buffer é recalculada para cada linha.


Função espacial utilizada sem filtro espacial

Uma junção espacial pode ser muito lenta se não houver um filtro de bounding box.

Exemplo recomendado:

SELECT *
FROM routes r
JOIN communes c
ON r.geom && c.geom
AND ST_Intersects(r.geom, c.geom);

O operador && utiliza o índice espacial.


Geometrias excessivamente complexas

Algumas geometrias contêm milhares de vértices.

Em certos casos pode ser útil utilizar:

ST_Simplify(geom, tolerance)

ou armazenar uma versão simplificada.


Estatísticas PostgreSQL desatualizadas

Se a tabela foi fortemente modificada, o PostgreSQL pode escolher um plano de execução ruim.

Atualizar estatísticas:

VACUUM ANALYZE


Exemplo real de otimização

Suponha uma consulta que procura estradas dentro de um município.

Consulta inicial:

SELECT r.*
FROM routes r, communes c
WHERE ST_Intersects(r.geom, c.geom)
AND c.nom = ‘Paris’;

Tempo de execução: 45 segundos

Versão otimizada

SELECT r.*
FROM routes r
JOIN communes c
ON r.geom && c.geom
AND ST_Intersects(r.geom, c.geom)
WHERE c.nom = ‘Paris’;

Com:

  • índice espacial
  • filtro de bounding box

Tempo de execução: menos de um segundo


Checklist rápida para diagnosticar uma consulta PostGIS lenta

Quando uma consulta demora demais, verifique:

✔ a consulta com EXPLAIN ANALYZE
✔ a presença de um índice espacial
✔ o uso de operadores compatíveis com índices
✔ a complexidade das geometrias
✔ a presença de um filtro por atributo
✔ as estatísticas PostgreSQL (ANALYZE)


Conclusão

Quando uma consulta PostGIS é lenta, é importante seguir uma abordagem progressiva:

  • analisar a consulta com EXPLAIN ANALYZE
  • verificar os índices espaciais
  • utilizar operadores compatíveis com índices
  • simplificar as geometrias quando necessário
  • manter as estatísticas da base de dados atualizadas.

Com essas etapas simples, muitas vezes é possível reduzir o tempo de execução de vários minutos para apenas alguns segundos.

Na maioria dos casos, uma consulta PostGIS lenta está relacionada a um índice ausente ou a um plano de execução inadequado. Uma análise metódica com EXPLAIN ANALYZE quase sempre permite identificar o problema.


Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Are you human? Please solve:Captcha