Cómo optimizar consultas espaciales en PostGIS

Las consultas espaciales en bases de datos pueden volverse extremadamente lentas cuando el volumen de datos crece o cuando no están correctamente optimizadas.

Si trabajas con miles (o millones) de geometrías en PostGIS, seguramente te ha pasado:

  • Una consulta que antes tardaba segundos ahora tarda minutos.
  • Un ST_Intersects bloquea el servidor.
  • El visor SIG parece “colgado”.
  • El CPU se dispara.

En este artículo veremos cómo diagnosticar y optimizar consultas espaciales paso a paso:

1. Comprueba si tienes índice espacial (el error más común)

El 80% de los problemas de rendimiento en PostGIS se deben a la ausencia de índices espaciales.

Para comprobarlo:

\d nombre_tabla

Si no aparece un índice GIST sobre la geometría, créalo:

CREATE INDEX idx_tabla_geom
ON nombre_tabla
USING GIST (geom);

Después, ejecuta:

VACUUM ANALYZE nombre_tabla;
  • Sin índice espacial, PostGIS hará un sequential scan completo.
  • Con índice, utilizará un index scan.

La diferencia puede ser brutal.

2. Usa EXPLAIN ANALYZE

Nunca optimices sin saber qué está pasando. Ejecuta:

EXPLAIN ANALYZE
SELECT *
FROM parcelas p
JOIN carreteras c
ON ST_Intersects(p.geom, c.geom);

Busca:

  • Seq Scan → mala señal.
  • Index Scan → correcto.
  • Tiempo total de ejecución.
  • Filas estimadas vs filas reales.

Esto te dirá si el índice está funcionando.

3. Sustituye en tus consultas ST_Buffer por ST_DWithin cuando sea posible

Consulta lenta típica:

SELECT *
FROM parcelas p
JOIN carreteras c
ON ST_Intersects(
p.geom,
ST_Buffer(c.geom, 500)
);

Problema:

ST_Buffer genera geometrías nuevas en cada ejecución → costoso.

Alternativa optimizada:

SELECT *
FROM parcelas p
JOIN carreteras c
ON ST_DWithin(p.geom, c.geom, 500);

ST_DWithin usa índices espaciales y es mucho más eficiente.

Esta optimización sola puede reducir el tiempo de minutos a segundos.

4. Reduce la complejidad geométrica

Geometrías muy detalladas = consultas lentas.

Puedes simplificar previamente:

UPDATE parcelas
SET geom = ST_Simplify(geom, 5);

O crear una vista optimizada:

CREATE MATERIALIZED VIEW parcelas_simplificadas AS
SELECT id, ST_Simplify(geom, 5) AS geom
FROM parcelas;

Para visualización web o análisis preliminar, es más que suficiente.

5. Evita SELECT * (reduce datos innecesarios)

Esto:

SELECT *
FROM parcelas
WHERE ST_Intersects(...);

Es menos eficiente que:

SELECT id, superficie
FROM parcelas
WHERE ST_Intersects(...);

Especialmente cuando la tabla tiene muchos campos.

Menos datos transferidos = mejor rendimiento.

6. Usa bounding box cuando sea posible

PostGIS puede usar el operador && (bounding box):

SELECT *
FROM parcelas p
JOIN carreteras c
ON p.geom && c.geom
AND ST_Intersects(p.geom, c.geom);

Primero filtra por caja envolvente (rápido), luego aplica la intersección real.

En grandes volúmenes mejora considerablemente.

7. Verifica el SRID (error silencioso frecuente)

Si las capas están en diferentes sistemas de referencia y usas ST_Transform dentro de la consulta:

ST_Intersects(
ST_Transform(p.geom, 25830),
c.geom
)

Estás forzando transformación por cada fila.

Solución:

  • Unificar SRID previamente.
  • O crear columna transformada e indexada.

8. Crea índices compuestos si el filtro no es solo espacial

Consulta típica:

SELECT *
FROM parcelas
WHERE municipio = 'Ávila'
AND ST_Intersects(...);

Crea índice combinado:

CREATE INDEX idx_municipio_geom
ON parcelas
USING GIST (geom)
WHERE municipio = 'Ávila';

Esto reduce drásticamente el conjunto de datos evaluado.

9. Usa tablas materializadas para análisis pesados

Si ejecutas siempre la misma consulta compleja:

CREATE MATERIALIZED VIEW analisis_final AS
SELECT ...

Luego solo refrescas cuando sea necesario:

REFRESH MATERIALIZED VIEW analisis_final;

Ideal para alimentar visores web o servicios desde GeoServer.

Resultado: de minutos a segundos

Una consulta espacial mal optimizada puede tardar 3–5 minutos.

Con:

  • Índices adecuados.
  • Uso correcto de ST_DWithin.
  • Simplificación geométrica.
  • EXPLAIN ANALYZE.

Es habitual reducirla a menos de 5–10 segundos.

En entornos productivos esto marca la diferencia entre un sistema usable y uno frustrante.

Conclusión

Optimizar consultas espaciales en PostGIS no es opcional cuando trabajas con grandes volúmenes de datos.

No se trata solo de saber SQL.

Se trata de entender:

  • Cómo funcionan los índices espaciales.
  • Cómo evalúa PostgreSQL una consulta.
  • Cómo minimizar cálculos geométricos innecesarios.

Y ahí es donde un perfil SIG con conocimientos avanzados de bases de datos marca la diferencia.

Deja un comentario