8 votos

¿Por qué no utiliza consulta de PostGIS índice espacial?

Estoy teniendo un problema con una consulta espacial que no está haciendo uso de los índices.

Mi esquema es:

CREATE TABLE geoplanet_place
(
  woeid integer NOT NULL,
  "name" character varying(300) NOT NULL,
  admin_1 character varying(300),
  coords geometry NOT NULL,
  bbox geometry NOT NULL,
  CONSTRAINT geoplanet_place_pkey PRIMARY KEY (woeid),
  CONSTRAINT enforce_dims_bbox CHECK (st_ndims(bbox) = 2),
  CONSTRAINT enforce_dims_coords CHECK (st_ndims(coords) = 2),
  CONSTRAINT enforce_geotype_bbox CHECK (geometrytype(bbox) = 'POLYGON'::text OR bbox IS NULL),
  CONSTRAINT enforce_geotype_coords CHECK (geometrytype(coords) = 'POINT'::text OR coords IS NULL),
  CONSTRAINT enforce_srid_bbox CHECK (st_srid(bbox) = 4326),
  CONSTRAINT enforce_srid_coords CHECK (st_srid(coords) = 4326)
)
WITH (
  OIDS=FALSE
);

Mi índices son:

CREATE INDEX geoplanet_place_bbox_id
  ON geoplanet_place
  USING gist
  (bbox);

CREATE INDEX geoplanet_place_coords_id
  ON geoplanet_place
  USING gist
  (coords);

Consulta Un:

SELECT "geoplanet_place"."woeid", "geoplanet_place"."name", "geoplanet_place"."admin_1"
FROM "geoplanet_place"
WHERE "geoplanet_place"."bbox" && ST_Expand(ST_GeomFromText('POINT (-71.4119869999999963 41.8238720000000015)', 4326), 16093.44)
    AND ST_distance_sphere("geoplanet_place"."coords", ST_GeomFromText('POINT (-71.4119869999999963 41.8238720000000015)', 4326)) <= 16093.44
ORDER BY "geoplanet_place"."woeid" ASC
LIMIT 5;

Ejecución de EXPLICAR ANALIZAR en Consulta a la producción:

 Limit  (cost=0.00..56.00 rows=5 width=24) (actual time=1440.482..1451.604 rows=5 loops=1)
   ->  Index Scan using geoplanet_place_pkey on geoplanet_place  (cost=0.00..20018585.21 rows=1787420 width=24) (actual time=1440.477..1451.583 rows=5 loops=1)
         Filter: ((bbox && '0103000020E61000000100000005000000CFF6E80D6D92CFC0134548DDCE59CFC0CFF6E80D6D92CFC02BC58EC6A183CF406F13EE95034BCF402BC58EC6A183CF406F13EE95034BCF40134548DDCE59CFC0CFF6E80D6D92CFC0134548DDCE59CFC0'::geometry) AND (st_distance_sphere(coords, '0101000020E610000023D8B8FE5DDA51C0890B40A374E94440'::geometry) <= 16093.44::double precision))
 Total runtime: 1451.657 ms
(4 rows)

Supongo que el plan está utilizando el índice, ya que la consulta se completa rápidamente, pero no menciona el índice en cualquier lugar.


Consulta B se Consulta Una reescrito para usar ST_DWithin(). Esta llamada a la función se supone que es equivalente a la Consulta de Una cláusula where.
Consulta B:

SELECT "geoplanet_place"."woeid", "geoplanet_place"."name", "geoplanet_place"."admin_1"
FROM "geoplanet_place"
WHERE ST_DWithin("geoplanet_place"."bbox", ST_GeomFromText('POINT (-71.4119869999999963 41.8238720000000015)', 4326), 16093.44)
ORDER BY "geoplanet_place"."woeid" ASC
LIMIT 5;

Ejecución de EXPLICAR en la Consulta de B, se obtiene:

 Limit  (cost=1884535.96..1884535.97 rows=5 width=24)
   ->  Sort  (cost=1884535.96..1884535.98 rows=9 width=24)
         Sort Key: woeid
         ->  Seq Scan on geoplanet_place  (cost=0.00..1884535.82 rows=9 width=24)
               Filter: ((bbox && '0103000020E61000000100000005000000CFF6E80D6D92CFC0134548DDCE59CFC0CFF6E80D6D92CFC02BC58EC6A183CF406F13EE95034BCF402BC58EC6A183CF406F13EE95034BCF40134548DDCE59CFC0CFF6E80D6D92CFC0134548DDCE59CFC0'::geometry) AND ('0101000020E610000023D8B8FE5DDA51C0890B40A374E94440'::geometry && st_expand(bbox, 16093.44::double precision)) AND _st_dwithin(bbox, '0101000020E610000023D8B8FE5DDA51C0890B40A374E94440'::geometry, 16093.44::double precision))
(5 rows)

Yo no permiten EXPLICAR ANALIZAR en Consulta B a terminar ya que estaba tomando mucho tiempo.

Corrí a ANALIZAR para ver si es de ayuda, pero nada cambió:

ANALYZE VERBOSE geoplanet_place (bbox, coords);

Preguntas:

  1. ¿Por qué el resultado de EXPLICAR en la Consulta de Un no dicen nada acerca de los índices?
  2. ¿Por qué la Consulta B resultado en un plan de consulta diferentes cuando debería ser equivalente a Una Consulta?
  3. ¿Qué debo hacer para que la Consulta B será rápido?
  4. Hay un problema con mi índices? Voluntad de cambio de las estadísticas sobre la geometría de las columnas de cambiar nada?

Enlaces:

  1. La construcción de Índices para PostGIS: http://postgis.net/docs/using_postgis_dbmanagement.html#id558306
  2. ST_DWithin: http://postgis.net/docs/ST_DWithin.html
  3. Estadísticas Utilizado por el Planificador: http://www.postgresql.org/docs/8.4/interactive/planner-stats.html

7voto

dlanod Puntos 8661

Su primera consulta es la utilización de un índice no sólo en la espacial. Ver el Índice de Escanear con geoplanet_place_pkey. Por lo tanto es más eficiente utilizar el id de la clave ya que están haciendo un PEDIDO por la columna y su filtro espacial cubre la totalidad de la tabla.

El índice espacial no se utiliza debido a su ST_Expand es demasiado grande. Usted tiene una geometría pero en su larga lat. El ampliar las unidades son, por tanto, en long lat. Mi dios no puedo entender cómo gran 16093.44 grados. que cubriría toda la tabla y, a continuación, algunos lo tanto, el índice es inútil y Postgres es lo suficientemente inteligente como para darse cuenta de eso.

Si vas a hacer este uso de la geografía de tipo de datos y, a continuación, su 16093.44 sería en metros y válido y no necesita que ST_Spheriod llamada.

desde el ST_Dwithin geograpy llamada se ocuparía de todo.

por ejemplo,


CREATE TABLE geoplanet_place
(
  woeid integer NOT NULL,
  "name" character varying(300) NOT NULL,
  admin_1 character varying(300),
  coords geography(POINT,4326) NOT NULL,
  bbox geography(POLYGON,4326) NOT NULL
)

y entonces, en lugar de ST_GeomFromText uso ST_GeogFromText

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