Es una tabla de puntos. ~ 1M de registros
SELECT COUNT(*) as value FROM alasarr_social_mv s;
Output: 976270
Parece que st_intersects obliga a usar los índices espaciales, pero && no lo hace.
Muestra usando ST_Intersects
(282ms)
SELECT COUNT(*) as value
FROM alasarr_social_mv
WHERE ST_Intersects(
the_geom_webmercator,
ST_MakeEnvelope(-410961,4920492,-402305,4926887,3857)
)
Aggregate (cost=34370.18..34370.19 rows=1 width=0) (actual time=282.715..282.715 rows=1 loops=1)
-> Bitmap Heap Scan on alasarr_social_mv s (cost=5572.17..34339.84 rows=60683 width=0) (actual time=21.574..240.195 rows=178010 loops=1)
Recheck Cond: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
Filter: _st_intersects(the_geom_webmercator, '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
Heap Blocks: exact=4848
-> Bitmap Index Scan on alasarr_social_mv_gix (cost=0.00..5569.13 rows=182050 width=0) (actual time=20.836..20.836 rows=178010 loops=1)
Index Cond: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
Planning time: 0.192 ms
Execution time: 282.758 ms
Muestra usando &&
(414ms)
SELECT COUNT(*) as value
FROM alasarr_social_mv
WHERE the_geom_webmercator &&
ST_MakeEnvelope(-410961,4920492,-402305,4926887,3857)
Aggregate (cost=22535.97..22535.97 rows=1 width=0) (actual time=414.314..414.314 rows=1 loops=1)
-> Seq Scan on alasarr_social_mv (cost=0.00..22444.94 rows=182050 width=0) (actual time=0.017..378.427 rows=178010 loops=1)
Filter: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
Rows Removed by Filter: 798260
Planning time: 0.134 ms
Execution time: 414.343 ms
Versión PostGIS
POSTGIS="2.2.2" GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.0, released 2014/04/16" LIBXML="2.7.8" LIBJSON="UNKNOWN" (core procs from "2.2.2" need upgrade) RASTER (raster procs from "2.2.2" need upgrade) – alasarr 2 mins ago
postgis
carto
postgis-2.2
alasarr
fuente
fuente
Respuestas:
Este tipo de hallazgo aparece con bastante frecuencia, y es un poco oscuro, por lo que vale la pena repetirlo. Si define una geometría dentro de una función que la usa, como ST_Intersects o && (que ST_Intersects usa debajo del capó), entonces el planificador de consultas elige un escaneo completo de la tabla, ya que "no" tiene conocimiento del resultado de la creación de la geometría función, es decir, ST_MakeEnvelope en este caso. Si define la geometría que desea verificar para la intersección en un CTE, entonces el optimizador se ocupa de una cantidad conocida y utilizará un índice espacial, si está disponible.
Entonces, reescribiendo su consulta como:
ahora usará un índice espacial. Del mismo modo, && ahora usará un índice para verificar un cuadro delimitador y (aunque no puedo probar sus datos), debería ser más rápido que ST_Intersects.
Curiosamente, en su consulta, ST_Intersects está utilizando un índice de escaneo de mapa de bits (no un resumen), mientras que && no está utilizando ningún índice. Entonces, ambas consultas serán más rápidas con el CTE, pero && ahora deberían ser más rápidas que ST_Intersects.
Hay más explicaciones de lo que está sucediendo en esta pregunta y sus respuestas / comentarios .
EDITAR : Para hacer esto explícito, si observa la definición de ST_Intersects en postgis.sql (que se llama
CREATE EXTENSION postgis
y se encuentra en el directorio contrib de su instalación de Postgres), verá:incluyendo el comentario: índice mágico en línea.
fuente