Penguatan Kinerja Melalui Indeks GIST untuk Poin dalam Kueri Polygon

10

Saya memiliki dua tabel: lokasi (id, region_id, the_geom) dan region (id, the_geom). Untuk setiap titik lokasi, saya ingin menentukan wilayah tempat ia berada:

UPDATE locations SET region_id = 
 (SELECT id FROM regions 
  WHERE ST_Within(locations.the_geom,regions.the_geom)
 );

Apakah masuk akal untuk membangun indeks GIST pada titik-titik lokasi? Saya akan membangun indeks pada poligon wilayah tetapi saya tidak yakin tentang poinnya. Apakah itu mempercepat permintaan?

underdark
sumber

Jawaban:

14

Jawaban singkat: No. Dengan jenis query UPDATE, kita memperbarui setiap baris dalam locations( "Seq Scan"), dan indeks GIST di the_geomdalam regionscukup dalam membantu baris batas untuk ST_Withinkondisi untuk pasangan-up baris langsung dari regions.


Jawaban yang lebih panjang: Keajaiban untuk mencari tahu ini adalah membandingkan apa yang Anda dapatkan dari menjelaskan kueri . Dari pgAdmin III, ada tombol "Jelaskan permintaan" di bagian atas editor kueri, atau dari pgsql, cukup awali permintaan Anda dengan "jelaskan":

postgis=# explain UPDATE locations SET region_id =
postgis-#  (SELECT id FROM regions
postgis(#   WHERE ST_Within(locations.the_geom, regions.the_geom)
postgis(#  );
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..8755.54 rows=1000 width=110)
   SubPlan 1
     ->  Index Scan using regions_gist_the_geom on regions  (cost=0.00..8.52 rows=1 width=4)
           Index Cond: ($0 && the_geom)
           Filter: _st_within($0, the_geom)
(5 rows)

Anda tidak perlu memahami semua yang batuk di sini. Hal utama untuk dilihat di sini adalah di bagian paling dalam (SubPlan 1) yang mengindikasikan "Indeks" (= menggunakan indeks, yang dapat mempercepat banyak hal), dan bukan "Pemindaian Seq" (= pemindaian urutan, yaitu masing-masing memeriksa baris untuk melihat apakah itu di dalam, yang bisa lebih lambat). Jika Anda menambahkan / menghapus indeks GiST aktif locations, output dari kueri menjelaskan ini persis sama, sehingga kinerja kueri harus sama.

Namun, jika Anda melakukan sesuatu yang konyol, dan menghapus indeks GiST Anda dari regions, Anda melihat rencana permintaan yang berbeda dari permintaan yang sama seperti di atas:

                             QUERY PLAN
---------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..74288.00 rows=1000 width=110)
   SubPlan 1
     ->  Seq Scan on regions  (cost=0.00..74.05 rows=1 width=4)
           Filter: (($0 && the_geom) AND _st_within($0, the_geom))
(4 rows)

Hal yang penting untuk dilihat di antara kedua penjelasan kueri adalah perkiraan biaya maksimum .. kontras 74,05 di sini hingga 8,52 sebelumnya, jadi Anda berharap kueri ini lebih lambat.

Mike T
sumber