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:
- ¿Por qué el resultado de EXPLICAR en la Consulta de Un no dicen nada acerca de los índices?
- ¿Por qué la Consulta B resultado en un plan de consulta diferentes cuando debería ser equivalente a Una Consulta?
- ¿Qué debo hacer para que la Consulta B será rápido?
- Hay un problema con mi índices? Voluntad de cambio de las estadísticas sobre la geometría de las columnas de cambiar nada?
Enlaces:
- La construcción de Índices para PostGIS: http://postgis.net/docs/using_postgis_dbmanagement.html#id558306
- ST_DWithin: http://postgis.net/docs/ST_DWithin.html
- Estadísticas Utilizado por el Planificador: http://www.postgresql.org/docs/8.4/interactive/planner-stats.html