Это таблица очков. ~ 1 млн. Записей
SELECT COUNT(*) as value FROM alasarr_social_mv s;
Output: 976270
Похоже, что st_intersects заставляет использовать пространственные индексы, но && этого не делает.
Пример использования ST_Intersects
(282 мс)
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
Пример использования &&
(414 мс)
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
Версия 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
источник
источник
Ответы:
Подобные открытия встречаются довольно часто, и они немного неясны, поэтому стоит повторить. Если вы определяете геометрию в функции, которая ее использует, например, ST_Intersects или && (которую ST_Intersects использует под капотом), тогда планировщик запросов выбирает полное сканирование таблицы, так как «он» не знает о результате создания геометрии функция, т. е. ST_MakeEnvelope в этом случае. Если вы определяете геометрию, которую вы хотите проверить на пересечение в CTE, то оптимизатор работает с известным количеством и будет использовать пространственный индекс, если он доступен.
Итак, переписать ваш запрос как:
теперь будет использовать пространственный индекс. Аналогично, && теперь будет использовать индекс для проверки ограничивающего прямоугольника, и (хотя я не могу проверить ваши данные) должен быть быстрее, чем ST_Intersects.
Интересно, что в вашем запросе ST_Intersects использует индекс растрового сканирования (не гист), в то время как && не использует индекс. Таким образом, оба запроса будут выполняться быстрее с CTE, но теперь && должен быть быстрее, чем ST_Intersects.
Есть больше объяснений того, что происходит в этом вопросе и его ответах / комментариях .
РЕДАКТИРОВАТЬ : Чтобы сделать это явным, если вы посмотрите на определение ST_Intersects в postgis.sql (который вызывается
CREATE EXTENSION postgis
и находится в каталоге contrib вашей установки Postgres), вы увидите:в том числе комментарий: встроенный индекс магии.
источник