ST_DWithin đã nhanh hơn trong thử nghiệm của tôi so với ST_Intersects. Đó là điều đáng ngạc nhiên, đặc biệt là vì thuật toán hình học đã chuẩn bị được cho là sẽ khởi động trong những trường hợp như thế này. Tôi nghĩ có khả năng điều này sẽ nhanh hơn khá nhiều so với những gì tôi thể hiện ở đây.
Tôi đã làm thêm một số bài kiểm tra và hai điều gần gấp đôi tốc độ. Đầu tiên, tôi đã thử trên một máy tính mới hơn, nhưng vẫn là một máy tính xách tay khá bình thường, có thể ngoại trừ từ ssd -disks của SATA3.
Sau đó, truy vấn dưới đây mất 18 giây thay vì 62 giây trên máy tính xách tay cũ. Tiếp theo tôi thấy rằng tôi đã hoàn toàn sai trước đây khi tôi viết rằng chỉ số trên bảng điểm là không cần thiết. Với chỉ số đó, ST_Intersects hoạt động như mong đợi và mọi thứ trở nên rất nhanh. Tôi đã tăng số điểm trong bảng điểm lên 1 triệu điểm và truy vấn:
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);
chạy trong 72 giây. Vì có 1249 đa giác, 1249000000 thử nghiệm được thực hiện trong 72 giây. Điều đó làm cho khoảng 17000000 bài kiểm tra mỗi giây. Hoặc kiểm tra gần 14000 điểm so với tất cả các đa giác mỗi giây.
Từ bài kiểm tra này, 400000000 điểm của bạn để kiểm tra sẽ mất khoảng 8 giờ mà không gặp bất kỳ rắc rối nào với việc phân phối tải cho một số lõi. PostGIS không bao giờ dừng lại để gây ấn tượng với tôi :-)
Trước tiên, để trực quan hóa kết quả, bạn có thể thêm hình dạng điểm vào bảng kết quả, ví dụ mở nó trong QGIS và định kiểu nó với các giá trị duy nhất trên trường import_ct.
Thứ hai, vâng, bạn cũng có thể nhận được các điểm nằm ngoài bất kỳ đa giác nào bằng cách sử dụng nối phải (hoặc trái) như thế này:
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);
Tôi đã thực hiện một số thử nghiệm để xác minh xem có vẻ như PostGIS có thể.
Điều đầu tiên tôi không hiểu. Bạn có hai điểm mỗi hàng. Luôn luôn là cả hai điểm trong cùng một đa giác? Sau đó, nó là đủ để làm các tính toán trên một trong những điểm. Nếu chúng có thể ở hai đa giác khác nhau, bạn sẽ cần một cách để kết nối một hàng điểm với hai đa giác.
Từ các thử nghiệm có vẻ như có thể thực hiện được, nhưng bạn có thể cần một số giải pháp sáng tạo để phân tán tải trên nhiều lõi.
Tôi đã thử nghiệm trên một máy tính xách tay 4 năm tuổi với cpu lõi kép (khoảng 2,2 GHz tôi nghĩ), RAM 2 GB. Nếu bạn có 48 BG RAM, tôi đoán bạn cũng có nhiều năng lượng cpu hơn.
Những gì tôi đã làm là tạo một bảng điểm ngẫu nhiên với 100000 điểm như thế này:
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;
Sau đó thêm một gid như:
ALTER TABLE t ADD COLUMN GID SERIAL;
Sau đó chạy:
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);
mất khoảng 62 giây (so với kết quả ArcGIS của bạn với cùng số điểm). Kết quả là một bảng kết nối các điểm trong bảng t của tôi với gid trong bảng với đường điều tra dân số.
Với tốc độ đó, bạn sẽ làm được 200 điểm trong khoảng 34 giờ. Vì vậy, nếu nó là đủ với việc kiểm tra một trong những điểm, máy tính xách tay cũ của tôi có thể làm điều đó với một lõi.
Nhưng nếu bạn cần kiểm tra cả hai điểm thì có thể khó hơn.
Vì vậy, bạn có thể phân phối tải theo cách thủ công đến nhiều lõi bằng cách bắt đầu nhiều phiên dựa trên db và chạy các truy vấn khác nhau.
Trong ví dụ của tôi với 50000 điểm và hai lõi cpu tôi đã thử:
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);
trên một phiên db cùng lúc với khi chạy:
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);
trên một phiên db khác.
Điều đó mất khoảng 36 giây nên chậm hơn một chút so với ví dụ đầu tiên có lẽ phụ thuộc vào việc ghi đĩa cùng một lúc. Nhưng vì các lõi của bith đang hoạt động cùng một lúc nên tôi không mất hơn 36 giây.
Để liên minh bảng t1 và t2 a đã thử:
CREATE TABLE t3 AS
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
sử dụng khoảng nửa giây.
Vì vậy, với phần cứng mới hơn và phân phối tải trên nhiều lõi, điều này hoàn toàn có thể xảy ra ngay cả khi thế giới thực sẽ chậm hơn trường hợp thử nghiệm.
Có thể đáng chú ý rằng ví dụ này là từ Linux (Ubuntu). Sử dụng Windows sẽ là một câu chuyện khác. Nhưng tôi có tất cả các ứng dụng hàng ngày khác đang chạy nên máy tính xách tay được tải khá nhiều từ trước đó. Vì vậy, điều đó có thể mô phỏng trường hợp cửa sổ khá tốt, có thể, không mở bất cứ thứ gì ngoại trừ pgadmin.