ST_DWithin testimde ST_Iersters'ten daha hızlıydı. Bu şaşırtıcı, özellikle hazırlanan geometri algoritmasının bu gibi durumlarda devreye girmesi gerektiği için. Bunun gösterdiğimden çok daha hızlı olma ihtimali olduğunu düşünüyorum.
Biraz daha testler yaptım ve iki şey neredeyse 10 katına çıktı. İlk önce, daha yeni bir bilgisayarda denedim, ama hala oldukça sıradan bir dizüstü bilgisayar, belki de SATA3 ssd diskleri dışında.
Daha sonra aşağıdaki sorgu eski dizüstü bilgisayarda 62 saniye yerine 18 saniye sürdü. Daha sonra, puan tablosundaki endeksin gerekmediğini yazdığımda daha önce tamamen yanlış olduğumu öğrendim. Bu indeks yerinde iken ST_Intersects beklendiği gibi davrandı ve işler çok hızlı oldu. Puan tablosundaki puan sayısını 1 milyon puana ve sorguyu arttırdım:
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);
72 saniye içinde çalışır. 1249 poligon olduğu için 72 saniyede 1249000000 testi yapılır. Bu saniyede yaklaşık 17000000 test yapar. Veya saniyede tüm poligonlara karşı neredeyse 14000 puan test etmek.
Bu testten 400000000 test edilebilecek puanınız, yükü birkaç çekirdeğe dağıtmakta sorun yaşamadan yaklaşık 8 saat sürmelidir. PostGIS beni etkilemek için asla durmaz :-)
İlk olarak, sonucu görselleştirmek için sonuç geometrisini sonuç tablosuna ekleyebilir, örneğin QGIS'de açabilir ve import_ct alanında benzersiz değerlerle stillendirebilirsiniz.
İkincisi, evet, ayrıca böyle bir sağ (veya sol) birleşimini kullanarak herhangi bir poligonun dışına düşen noktaları elde edebilirsiniz:
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);
PostGIS'in mümkün olup olmadığını doğrulamak için bazı testler yaptım.
İlk önce anlamadığım bir şey var. Satır başına iki puanınız var. Her zaman her iki nokta da aynı poligonda mı? O zaman noktalardan bir tanesinde hesaplamaları yapmak yeterlidir. İki farklı poligonda olabilirlerse, bir nokta sırasını iki poligona bağlamanın bir yoluna ihtiyacınız olacaktır.
Testlerden mümkün gibi görünüyor, ancak yükü birden fazla işlemci çekirdeğine yaymak için yaratıcı bir çözüme ihtiyacınız olabilir.
İki çekirdekli centrino işlemci (yaklaşık 2.2GHz sanırım) 2GB RAM ile 4 yaşında bir dizüstü bilgisayarda test ettim. 48 BG RAM'iniz varsa sanırım çok daha fazla cpu gücünüz var.
Yaptığım şey, bunun gibi 100000 puan ile rastgele bir nokta tablosu oluşturmaktı:
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;
Sonra bir gid ekleyerek:
ALTER TABLE t ADD COLUMN GID SERIAL;
Sonra çalışıyor:
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);
yaklaşık 62 saniye sürer (ArcGIS sonucunuzla aynı miktarda puanla karşılaştırın). Sonuç, benim masamdaki t noktalarını sayım yolundaki masanın içindeki gid ile birleştiren bir tablodur.
Bu hızla yaklaşık 34 saatte 200 değirmen puanı yapacaksınız. Öyleyse, noktalardan birini kontrol etmek yeterliyse, eski dizüstü bilgisayarım bunu bir çekirdekle yapabilir.
Ancak her iki noktayı da kontrol etmeniz gerekirse, daha zor olabilir.
Daha sonra, db'ye karşı birden çok oturumu başlatarak ve farklı sorgular çalıştırarak yükü birden fazla çekirdeğe manuel olarak dağıtabilirsiniz.
Örneğimde 50000 puan ve iki cpu çekirdeği ile denedim:
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);
Bir db oturumunda koşarken aynı anda:
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);
başka bir db oturumunda.
Bu yaklaşık 36 saniye sürdü, bu yüzden muhtemelen aynı anda disk yazmaya bağlı olarak ilk örnekten biraz daha yavaştı. Ancak, çekirdek çekirdekleri aynı anda çalıştığı için zamanımın 36 saniyesinden fazla bir zaman almadı.
T1 ve t2 tablolarını birleştirmek için:
CREATE TABLE t3 AS
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
yaklaşık yarım saniye kullanarak.
Dolayısıyla, daha yeni donanım ve yükü birçok çekirdeğe dağıtmakla, gerçek dünya test durumundan daha yavaş olsa bile bu kesinlikle mümkün olmalıdır.
Örnegin Linux (Ubuntu) oldugunu farketmeye deger olabilir. Windows kullanarak başka bir hikaye olacak. Ancak çalışan diğer tüm günlük uygulamalarım var, böylece dizüstü bilgisayar eskisinden çok ağır bir şekilde yüklendi. Bu nedenle, windows kasasını pgadmin dışında bir şey açmadan oldukça iyi bir şekilde taklit edebilir.