Ini daftar poin. ~ Catatan 1 juta
SELECT COUNT(*) as value FROM alasarr_social_mv s;
Output: 976270
Sepertinya st_intersects memaksa untuk menggunakan indeks spasial tetapi && tidak.
Sampel menggunakan ST_Intersects
(282 ms)
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
Sampel menggunakan &&
(414 ms)
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 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
sumber
sumber
Jawaban:
Temuan semacam ini cukup sering muncul, dan agak tidak jelas, jadi layak untuk disajikan kembali. Jika Anda mendefinisikan geometri di dalam fungsi yang menggunakannya, seperti ST_Intersects atau && (yang digunakan ST_Intersects di bawah tenda), maka perencana kueri memilih pemindaian tabel penuh, karena "ia" tidak memiliki pengetahuan tentang hasil dari pembuatan geometri fungsi, yaitu, ST_MakeEnvelope dalam kasus ini .. Jika Anda mendefinisikan geometri yang ingin Anda periksa persimpangan dalam CTE, maka pengoptimal berurusan dengan kuantitas yang diketahui, dan akan menggunakan indeks spasial, jika tersedia.
Jadi, tulis ulang kueri Anda sebagai:
sekarang akan menggunakan indeks spasial. Demikian juga, && sekarang akan menggunakan indeks untuk memeriksa kotak pembatas, dan, (sementara saya tidak dapat menguji data Anda), harus lebih cepat daripada ST_Intersects.
Menariknya, dalam kueri Anda, ST_Intersects menggunakan indeks pemindaian bitmap (bukan inti), sedangkan && tidak menggunakan indeks. Jadi, kedua kueri akan lebih cepat dengan CTE, tetapi && sekarang seharusnya lebih cepat dari ST_Intersects.
Ada lebih banyak penjelasan tentang apa yang terjadi dalam pertanyaan ini dan jawaban / komentarnya .
EDIT : Untuk membuat ini eksplisit, jika Anda melihat definisi ST_Intersects di postgis.sql (yang dipanggil oleh
CREATE EXTENSION postgis
dan ditemukan di direktori contrib dari instalasi Postgres Anda), Anda akan melihat:termasuk komentar: inline magic indeks.
sumber