Indeks spasial PostgreSQL / PostGIS - tidak ada percepatan

15

Saya memiliki tabel spasial dalam database PostgreSQL / PostGIS. Setiap baris di dalamnya mewakili suatu Poligon. Bentuknya sebagai berikut:

+----+--------+
|gid |   way  |
+----+--------+
|241 | 01030..|

Kolom geometris adalah "cara" yang berisi geometri untuk poligon. Di WKT itu adalah: POLYGON (('....')). Saya melakukan banyak pertanyaan ST_Contains pada tabel ini, untuk menguji apakah dua poligon terkandung satu sama lain misalnya:

Select ST_Contains(a.way, b.way) From table AS a, table AS b Where a.gid = 15 And b.gid = 16

Saya bertanya-tanya bagaimana cara mempercepat permintaan ini dan menambahkan indeks spasial di atas meja:

CREATE INDEX table_way_gist ON table USING gist(way);

Tapi sebenarnya saya tidak melihat kecepatan. Saya membuat indeks SETELAH saya mengisi tabel dengan semua poligon SEBELUM saya melakukan query ST_Contains. Haruskah indeks ditambahkan sebelum mengisi tabel? Apakah ada persyaratan khusus di atas meja untuk bekerja dengan indeks? Proyeksi (srid) dari cara kolom geometrik diatur ke 900913.

Saya menggunakan: psql (PostgreSQL) 9.1.4 / POSTGIS = "1.5.3"

MichiMichbeck
sumber

Jawaban:

16

Indeks paling efisien untuk kueri yang dinyatakan dalam pertanyaan Anda adalah yang ada di gid karena hanya kolom yang muncul di ekspresi where:

 CREATE INDEX table_gid ON table (gid);

Anda dapat dengan aman menjatuhkan indeks inti karena hanya akan menghabiskan ruang dan memperlambat sisipan / pembaruan / penghapusan.

Penjelasan panjang

Seperti yang saya katakan, indeks paling efektif dalam kasus Anda adalah yang ada di gid karena akan memungkinkan mesin db untuk mengambil baris lebih cepat (dengan pengambilan biasanya menjadi bagian paling lambat dari proses). Setelah itu mungkin akan lebih baik menghitung hasil

  ST_Contains(a.way, b.way)

penekanan tanpa melihat indeks. Alasannya adalah bahwa perencana permintaan kemungkinan akan memperkirakan bahwa biaya tambahan untuk mencari indeks inti pada kedua kolom dibandingkan mencari a.way dan b.way secara langsung tidak sebanding dengan upaya karena jumlah total baris yang dicari mungkin sangat kecil terutama jika indeksnya unik.

Sebagai aturan umum, ingatlah bahwa perencana mungkin akan menyukai pemindaian tabel daripada pemindaian indeks untuk kumpulan data kecil (ukuran dataset diperkirakan dengan melihat statistik tabel).

unicoletti
sumber
Itu membuat masalah lebih jelas bagi saya. Saya akan mencobanya. Jadi, jika saya memasukkan kueri ST_Contains () ke dalam klausa WHERE, indeks spasial seharusnya benar-benar membantu? Saya pikir saya harus mengatur ulang skrip saya untuk menelepon ST_Contains dalam klausa WHERE. Saat ini saya mengulangi semua poligon dan selalu menguji dua poligon secara terpisah.
MichiMichbeck
?? Anda merasa bahwa indeks spasial memperlambat segalanya? Itu baru bagi saya karena di mana saya bekerja kami memiliki indeks spasial untuk setiap tabel dan saya bertanya-tanya apakah itu praktik yang buruk
Luffydude
13

Sebagai unicoletti dikatakan , indeks inti pada kolom geometri hanya akan berfungsi jika Anda menggunakan ST_Contains () dalam ekspresi WHERE.

Misalnya, jika Anda ingin mengetahui semua poligon yang mengandung satu sama lain, Anda dapat menggunakan sesuatu seperti ini:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

Dalam hal ini, tergantung pada ukuran tabel Anda dan kompleksitas geometri Anda, indeks inti harus memberikan kecepatan yang signifikan, karena ST_Contains akan mulai dengan memfilter poligon dengan membandingkan kotak batasnya sebelum benar-benar memeriksa geometri lengkapnya. Anda dapat melihat penjelasan kecil di Tutorial OpenGeo .

Alexandre Neto
sumber
Ya saya mengerti, saya perlu pertanyaan ini untuk melibatkan uji batas indeks. Thx Alexandre. (Saya akan menandai unicoletti sebagai solusi, karena ia cepat dan menyelesaikan masalah ini kepada saya)
MichiMichbeck