ST_DWithin lebih cepat dalam pengujian saya daripada ST_Intersects. Itu mengejutkan, terutama karena algoritma geometri yang sudah disiapkan seharusnya digunakan untuk kasus-kasus seperti ini. Saya pikir ada kemungkinan ini akan jauh lebih cepat daripada yang saya tunjukkan di sini.
Saya melakukan beberapa tes lagi dan dua hal kecepatannya hampir dua kali lipat. Pertama, saya mencoba di komputer yang lebih baru, tetapi masih laptop yang cukup biasa, mungkin kecuali dari SATA3 ssd -disks.
Kemudian permintaan di bawah ini memakan waktu 18 detik, bukan 62 detik di laptop lama. Selanjutnya saya menemukan bahwa saya benar-benar salah sebelumnya ketika saya menulis bahwa indeks pada tabel-titik tidak perlu. Dengan indeks itu, ST_Intersects bertindak sesuai yang diharapkan dan segalanya menjadi sangat cepat. Saya meningkatkan jumlah poin di tabel poin menjadi 1 juta poin dan permintaan:
CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id
FROM imported_ct , t WHERE ST_Intersects(imported_ct.geom , t.geom);
berjalan dalam 72 detik. Karena ada 1249 poligon, uji 1249000000 dilakukan dalam 72 detik. Itu menghasilkan sekitar 17000000 tes per detik. Atau menguji hampir 14.000 poin terhadap semua poligon per detik.
Dari pengujian ini, 400000000 poin Anda untuk diuji harus memakan waktu sekitar 8 jam tanpa kesulitan dengan mendistribusikan beban ke beberapa core. PostGIS tidak pernah berhenti mengesankan saya :-)
Pertama, untuk memvisualisasikan hasil, Anda dapat menambahkan titik geometri ke tabel yang dihasilkan, buka di QGIS misalnya dan gaya dengan nilai unik pada bidang import_ct.
Kedua, ya, Anda juga bisa mendapatkan poin yang berada di luar poligon apa pun dengan menggunakan gabungan kanan (atau kiri) seperti ini:
CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id
FROM imported_ct right join t ON ST_Intersects(imported_ct.the_geom , t.geom);
Saya melakukan beberapa tes untuk memverifikasi jika tampaknya mungkin PostGIS.
Pertama, sesuatu yang tidak saya mengerti. Anda memiliki dua poin per baris. Apakah kedua poin selalu dalam poligon yang sama? Maka cukup melakukan perhitungan pada salah satu poin. Jika mereka bisa dalam dua poligon yang berbeda, Anda akan membutuhkan cara untuk menghubungkan satu baris baris ke dua poligon.
Dari tes ini sepertinya bisa dilakukan, tetapi Anda mungkin memerlukan beberapa solusi kreatif untuk menyebarkan beban lebih dari satu cpu-core.
Saya menguji pada laptop berusia 4 tahun dengan cpu dual core centrino (kira-kira 2.2GHz saya kira), RAM 2GB. Jika Anda memiliki 48 BG RAM, saya kira Anda juga memiliki lebih banyak cpu-power.
Apa yang saya lakukan adalah membuat tabel poin acak dengan 100000 poin seperti ini:
CREATE TABLE t AS
WITH r AS
(SELECT ST_Extent(the_geom)::geometry ext FROM imported_ct)
SELECT ST_Point(x,y) AS geom FROM
(SELECT GENERATE_SERIES(1,100000)) s,
(SELECT ST_Xmin(ext)+(random()*(ST_Xmax(ext)-ST_Xmin(ext))) x, ST_Ymin(ext)+(random()*(ST_Ymax(ext)-ST_Ymin(ext))) y FROM r
) f;
Kemudian menambahkan gid seperti:
ALTER TABLE t ADD COLUMN GID SERIAL;
Kemudian jalankan:
CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE ST_Dwithin(imported_ct.the_geom , t.geom,0);
membutuhkan sekitar 62 detik (bandingkan dengan hasil ArcGIS Anda dengan jumlah poin yang sama). Hasilnya adalah tabel yang menghubungkan titik-titik di tabel saya t dengan gid di tabel dengan saluran sensus.
Dengan kecepatan itu Anda akan melakukan 200 poin pabrik dalam waktu sekitar 34 jam. Jadi, jika cukup dengan memeriksa salah satu intinya, laptop lama saya dapat melakukannya dengan satu inti.
Tetapi jika Anda perlu memeriksa kedua poin itu mungkin lebih sulit.
Kemudian Anda dapat secara manual mendistribusikan beban ke lebih dari satu inti dengan memulai beberapa sesi melawan db dan menjalankan kueri yang berbeda.
Dalam contoh saya dengan 50.000 poin dan dua cpu-core saya mencoba:
CREATE TABLE t1 as
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE t.gid >50000 and ST_Dwithin(imported_ct.the_geom , t.geom,0);
pada satu db-sesi sekaligus dengan menjalankan:
CREATE TABLE t2 as
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE t.gid <=50000 and ST_Dwithin(imported_ct.the_geom , t.geom,0);
pada sesi db lain.
Itu memakan waktu sekitar 36 detik sehingga sedikit lebih lambat dari contoh pertama mungkin tergantung pada penulisan disk pada saat yang sama. Tetapi karena core bith bekerja pada saat yang sama, tidak memerlukan lebih dari 36 detik waktu saya.
Untuk tabel gabungan t1 dan t2 a dicoba:
CREATE TABLE t3 AS
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
menggunakan sekitar setengah detik.
Jadi, dengan perangkat keras yang lebih segar dan mendistribusikan beban ke banyak core, ini harus benar-benar mungkin bahkan jika dunia nyata akan lebih lambat daripada test case.
Mungkin perlu dicatat bahwa contohnya adalah dari Linux (Ubuntu). Menggunakan Windows akan menjadi cerita lain. Tetapi saya memiliki semua aplikasi harian lainnya berjalan sehingga laptop ini cukup banyak dimuat dari sebelumnya. Jadi itu mungkin mensimulasikan case windows cukup baik mungkin, tanpa membuka apa pun kecuali pgadmin.