Saya punya tabel PostgreSQL 9.1 dengan ratusan ribu TITIK PostGIS. Untuk masing-masing ini saya ingin mencari titik terdekat di tabel POINT lain. Poin di tabel kedua mewakili grid di seluruh dunia, jadi saya tahu akan selalu ada kecocokan dalam 1 derajat. Ini adalah permintaan yang saya gunakan sejauh ini, yang menggunakan indeks GIST, jadi cukup cepat (sekitar total 30 detik).
SELECT DISTINCT ON (p.id)
p.id, ST_AsText(p.pos)
, ST_AsText(first_value(g.location) OVER (PARTITION BY p.id ORDER BY ST_Distance(p.pos, g.location::geography)))
FROM point p
JOIN grid g ON ST_DWithin(p.pos::geometry, g.location, 1)
Satu-satunya masalah adalah dateline. Poin grid hanya memiliki garis lintang 180, bukan -180. Saat menggunakan versi geometri dari ST_Distance, ini tidak mengembalikan poin di sisi lain dateline. Misalnya. jika p.pos adalah POINT(-179.88056 -16.68833)
titik kisi terdekat mungkin POINT(180 -16.25)
, tetapi kueri di atas tidak mengembalikannya. Apa cara terbaik untuk memperbaikinya?
Saya tidak benar-benar ingin memiliki dua koordinat untuk satu titik grid (-180 dan +180). Saya mencoba menambahkan fungsi saya sendiri yang memeriksa kasus khusus ini, tetapi kemudian permintaan tidak kembali dalam 5 menit, mungkin karena tidak dapat lagi menggunakan indeks. Saya juga mencoba menggunakan versi geografi ST_DWithin dan permintaan itu juga tidak kembali setelah 5 menit.
Jawaban:
OK, saya akhirnya menemukan cara untuk meretasnya yang tidak hanya bekerja di sekitar masalah dateline, tetapi juga lebih cepat.
Saya sangat terkejut melihat bahwa fungsi ini, yang dipanggil untuk setiap baris, lebih cepat dari fungsi jendela asli, tetapi - lebih dari 10 kali lebih cepat. Kinerja PostgreSQL benar-benar seni hitam!
sumber