Índices espaciales
Los índices GiST aceleran los operadores de caja delimitadora y el prefiltrado de distancia de PostGIS. Cree índices en columnas de geometría o geografía, escriba consultas que utilicen && o ST_DWithin, y mantenga estadísticas después de cargas espaciales masivas.
Receta
CREATE TABLE parcels (
id bigserial PRIMARY KEY,
geom extensions.geometry(Polygon, 4326) NOT NULL
);
CREATE INDEX parcels_geom_gist ON parcels USING gist (geom);
-- Amigable con el índice: superposición de caja delimitadora y luego filtro preciso
SELECT id
FROM parcels
WHERE geom && extensions.ST_Expand(
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.99, 40.75), 4326),
0.01
)
AND extensions.ST_Contains(
geom,
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.99, 40.75), 4326)
);Cuándo usar esto: Seq Scan en filtros espaciales, consultas de vista de mapa, o unión de tablas grandes de polígonos.
Ejemplo de trabajo
CREATE TABLE drivers (
id uuid PRIMARY KEY,
loc extensions.geography(Point, 4326) NOT NULL,
updated_at timestamptz DEFAULT now()
);
CREATE INDEX drivers_loc_gist ON drivers USING gist (loc);
-- ST_DWithin usa el índice para geografía
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, updated_at
FROM drivers
WHERE extensions.ST_DWithin(
loc,
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.99, 40.75), 4326)::extensions.geography,
1500 -- metros
)
ORDER BY updated_at DESC
LIMIT 50;
ANALYZE drivers;Qué demuestra esto:
- GiST en
geographypara consultas de radio en metros ST_DWithines el filtro de proximidad indexado idiomáticoEXPLAINdebería mostrarIndex Scan using drivers_loc_gistANALYZEdespués de actualizaciones masivas de ubicación
Profundización
GiST vs SP-GiST
| Índice | Uso en PostGIS | Notas |
|---|---|---|
| GiST | Predeterminado para geometría/geografía | Maduro, propósito general |
| SP-GiST | Algunas cargas de trabajo con muchos puntos | Probar antes de la adopción general |
| BRIN | Tablas enormes, geom ordenadas por inserción | Raro para datos espaciales irregulares |
Elección predeterminada: GiST a menos que las pruebas de rendimiento muestren lo contrario.
Operadores que usan GiST
-- Superposición de caja delimitadora de geometría (indexable)
geom1 && geom2
-- ST_DWithin con índice (usa && internamente para prefiltrado)
ST_DWithin(geog1, geog2, distance_meters)Las funciones que solo usan geometría exacta sin prefiltro de caja delimitadora pueden no usar el índice de manera eficiente (ST_Contains solo en una tabla enorme sin el guardián &&).
Índices multicolumna y parciales
-- Solo conductores activos
CREATE INDEX drivers_active_loc_gist ON drivers USING gist (loc)
WHERE updated_at > now() - interval '1 hour';
-- Combinación btree + gist: filtrar por tenant y luego espacial
CREATE INDEX parcels_tenant_gist ON parcels (tenant_id);
CREATE INDEX parcels_geom_gist ON parcels USING gist (geom);Aplique la igualdad de tenant_id antes de la operación espacial para SaaS multitenant.
Creación y mantenimiento de índices
CREATE INDEX CONCURRENTLY parcels_geom_gist ON parcels USING gist (geom);
-- Después de la importación masiva de shapefile
REINDEX INDEX CONCURRENTLY parcels_geom_gist;
ANALYZE parcels;
SELECT pg_size_pretty(pg_relation_size('parcels_geom_gist'));Los polígonos complejos producen árboles GiST grandes. Simplifique las geometrías para índices de vista general si es necesario (ver artículo de rendimiento).
Lista de verificación del plan de consulta
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...
-- Esperar: Index Scan using ..._gist
-- Señal de alerta: Seq Scan + Filter en un millón de filasTrampas comunes
- No hay índice en el cast de geografía solo en WHERE - La expresión no está indexada. Solución: Persistir la columna de geografía o indexar explícitamente la expresión funcional.
- ST_Distance sin DWithin - Ordena todas las filas. Solución: Límite
ST_DWithiny luegoORDER BY ST_Distanceen un conjunto pequeño. - SRID incorrecto en la columna de índice - Índice utilizado pero respuestas incorrectas. Solución: Restricciones SRID en el typmod de la columna.
- Caja delimitadora pequeña -
&&demasiado selectivo omite los bordes. Solución:ST_Expando tolerancia apropiada. - Bloqueo de CREATE INDEX - Bloquea escrituras en producción. Solución:
CONCURRENTLY. - Estadísticas obsoletas después de la importación masiva de GIS - Se elige Seq scan. Solución:
ANALYZEy considerar aumentardefault_statistics_targeten columnas de geometría si la carga de trabajo lo admite.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| BRIN en puntos agrupados | Registros GPS ordenados por tiempo | Distribución espacial aleatoria |
| Sin índice (tabla pequeña) | < 5k características | Capas de mapa de producción |
| Mosaicos de cuadrícula precalculados | Mapa base de solo lectura | Vectores editados frecuentemente |
| Índice espacial externo | ES geo_shape | Uniones espaciales relacionales |
Preguntas frecuentes
¿Tamaño del índice GiST?
Depende del número de vértices; polígonos complejos son más grandes que puntos. Monitorear pg_relation_size.¿Índice de geography vs geometry?
Ambos usan GiST; consultar con el tipo coincidente y ST_DWithin.¿Índice agrupado?
CLUSTER en GiST rara vez se usa; la partición es más común.¿Índice de geometría 3D?
GiST lo soporta; asegúrese de que las funciones coincidan con la dimensionalidad.¿Múltiples columnas de geometría?
GiST separado por cada columna utilizada en las consultas.¿Operador &&?
Superposición de caja delimitadora; patrón central de aceleración de índices.¿KNN ORDER BY?
Operador <-> para KNN de geometría en columna indexada en consultas soportadas.¿Replicación?
Los índices se replican con DDL de tabla en replicación física.¿Vacuum?
GiST se beneficia del vacuum rutinario después de actualizaciones intensivas.¿Límites en la nube?
Algunas instancias limitan las construcciones de índices concurrentes; programar mantenimiento.Relacionados
- Geometría vs Geografía - elección de tipo
- Rendimiento de PostGIS - simplificar y prefiltrar
- GIN y GiST - descripción general de GiST
- Conceptos básicos de diseño de índices - indexación general
- Mejores prácticas de PostGIS - validar entradas
Versiones de la pila: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PostGIS 3.5+, pgbouncer 1.x, y Patroni 3.x.