Índice espacial PostgreSQL / PostGIS - sin aceleración

15

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

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

La columna geométrica es "way", que contiene la geometría de un polígono. En WKT es: POLYGON (('....')). Estoy haciendo un montón de consultas ST_Contains en esta tabla, para probar si dos polígonos están contenidos entre sí, 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 agregué un índice espacial en la tabla:

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 realizar las consultas ST_Contains. ¿Debería agregarse el índice antes de llenar una tabla? ¿Hay requisitos especiales en la tabla para trabajar con el índice? La proyección (srid) de la forma de la columna geométrica se establece en 900913.

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

    
pregunta MichiMichbeck 20.12.2012 - 09:44

2 respuestas

15

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 donde:

 CREATE INDEX table_gid ON table (gid);

Puede descartar de forma segura el índice global, ya que solo consumirá espacio y retrasará las inserciones / actualizaciones / eliminaciones.

Explicación larga

Como dije, el índice más efectivo en su caso es el de gid, ya que permitirá que el motor db recupere las filas más rápido (siendo la recuperación la parte más lenta del proceso). Después de eso, probablemente se calculará mejor el resultado de la

  ST_Contains(a.way, b.way)

Expresión sin mirar el índice. La razón es que el planificador de consultas probablemente estimará que el costo adicional de buscar el índice gist en ambas columnas en lugar de buscar el a.way y b.way directamente no valen la pena, 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á una exploración de tabla sobre una exploración de índice para conjuntos de datos pequeños (los tamaños de conjuntos de datos se estiman mirando las estadísticas de la tabla).

    
respondido por el unicoletti 20.12.2012 - 09:56
12

Como ha dicho unicoletti , el índice global en la columna de geometría solo funcionará si usa ST_Contains () en la expresión WHERE.

Por ejemplo, si desea conocer todos los polígonos que se contienen entre sí, puede usar algo como esto:

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 la complejidad de sus geometrías, el índice global debe proporcionar una aceleración significativa, ya que ST_Contains comenzará a filtrar los polígonos comparando sus cuadros de límites antes de verificar realmente sus geometrías completas . Puede ver una pequeña explicación en el Tutorial de OpenGeo .

    
respondido por el Alexandre Neto 20.12.2012 - 11:09

Lea otras preguntas en las etiquetas