16 votos

Índice espacial Postgres/Postgis - no se acelera

Tengo una tabla espacial en una base de datos postgres/postgis. Cada fila en ella representa un polígono. Es de la siguiente forma:

+----+--------+
|gid |   way  |
+----+--------+
|241 | 01030..|

La columna geométrica es "camino" que contiene la geometría de un polígono. En WKT lo es: POLÍGONO(('....')). Estoy haciendo un montón de consultas ST_Contains en esta tabla, para comprobar si dos polígonos están contenidos el uno en el otro, por ejemplo:

Select ST_Contains(a.way, b.way) From table AS a, table AS b Where a.gid = 15 And b.gid = 16

Me preguntaba cómo acelerar esta consulta y añadí un índice espacial en la mesa:

CREATE INDEX table_way_gist ON table USING gist(way);

Pero en realidad no veo una aceleración. Creo el índice DESPUÉS de llenar la tabla con todos los polígonos ANTES de hacer las consultas ST_Contains. ¿Debería añadirse el índice antes de llenar una tabla? ¿Hay requisitos especiales en la tabla para trabajar con el índice? La proyección (srid) del camino de la columna geométrica se establece en 900913.

Estoy usando: psql (PostgreSQL) 9.1.4 / POSTGIS="1.5.3"

Thx por ayuda.

17voto

Celso Puntos 66

El índice más eficiente para la consulta expresada en su pregunta es el de gid ya que es la única columna que aparece en una expresión where:

 CREATE INDEX table_gid ON table (gid);

Puedes dejar de lado el índice gist, ya que sólo consumirá espacio y ralentizará las inserciones/actualizaciones/borrados.

Explicación larga

Como he dicho el índice más efectivo en tu caso es el de gid ya que permitirá al motor de la db recuperar las filas más rápidamente (siendo la recuperación normalmente la parte más lenta del proceso). Después de eso probablemente calculará mejor el resultado de la

  ST_Contains(a.way, b.way)

espresión sin mirar el índice. La razón es que el planificador de consultas probablemente estimará que el coste adicional de buscar el gist índice en ambas columnas frente a buscando el a.way y b.way directamente no vale la pena el esfuerzo, ya que el número total de filas a buscar es probablemente muy pequeño, especialmente si el índice es único.

Como regla general, recuerde que el planificador probablemente favorecerá un escaneo de tabla sobre un escaneo de índice para conjuntos de datos pequeños (el tamaño de los conjuntos de datos se estima mirando las estadísticas de la tabla).

15voto

sashkello Puntos 325

Como unicoletti dijo, el índice gist en la columna de geometría sólo funcionaría si se utiliza ST_Contains() en la expresión WHERE.

Por ejemplo, si quieres conocer todos los polígonos que se contienen entre sí, puedes utilizar algo así:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

En este caso, dependiendo del tamaño de su tabla y de la complejidad de sus geometrías, el índice gist debería proporcionar un aumento significativo de la velocidad, ya que ST_Contains empezará a filtrar los polígonos comparando sus cajas de límites antes de comprobar realmente sus geometrías completas. Puede ver una pequeña explicación en el Tutorial de OpenGeo .

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X