ST_DWithin 내 테스트에서 ST_Intersects보다 빠릅니다. 준비된 지오메트리 알고리즘이 이와 같은 경우에 적용되기 때문에 특히 놀랍습니다. 나는 이것이 내가 여기에 보여준 것보다 훨씬 빠를 가능성이 있다고 생각합니다.
나는 더 많은 테스트를했고 두 가지가 속도를 거의 두 배로 늘 렸습니다. 첫째, 나는 새로운 컴퓨터에서 시도했지만 SATA3 ssd -disks를 제외하고는 여전히 일반적인 랩톱입니다.
그런 다음 이전 노트북에서 62 초 대신 18 초가 걸렸습니다. 다음으로 포인트 테이블의 인덱스가 필요하지 않다고 썼을 때 완전히 잘못되었다는 것을 알았습니다. 이 인덱스가 있으면 ST_Intersects가 예상대로 작동하고 상황이 매우 빨라졌습니다. 포인트 테이블의 포인트 수를 백만 포인트로 늘리고 쿼리 :
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 초 안에 실행됩니다. 1249 개의 다각형이 있으므로 1249000000 개의 테스트가 72 초 안에 수행됩니다. 초당 약 17000000 개의 테스트가 수행됩니다. 또는 초당 모든 다각형에 대해 거의 14000 포인트를 테스트합니다.
이 테스트에서 400000000 포인트 테스트는로드를 여러 코어에 분배하는 데 아무런 어려움없이 약 8 시간이 소요됩니다. PostGIS는 나에게 감동을 멈추지 않습니다 :-)
먼저 결과를 시각화하기 위해 결과 지오메트리를 결과 테이블에 추가하고이를 QGIS에서 열고 import_ct 필드에서 고유 한 값으로 스타일을 지정할 수 있습니다.
둘째, 다음과 같이 오른쪽 (또는 왼쪽) 조인을 사용하여 다각형 바깥으로 떨어지는 점을 얻을 수도 있습니다.
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가 가능한지 확인하기 위해 몇 가지 테스트를 수행했습니다.
먼저 이해가 안되는 것. 행당 두 점이 있습니다. 두 점이 항상 같은 다각형에 있습니까? 그런 다음 포인트 중 하나에서 계산을 수행하면 충분합니다. 두 개의 다른 다각형에있을 수 있으면 한 점 행을 두 개의 다각형에 연결하는 방법이 필요합니다.
테스트에서 가능한 것처럼 보이지만 둘 이상의 CPU 코어에 부하를 분산시키기 위해서는 창의적인 솔루션이 필요할 수 있습니다.
듀얼 코어 센트리노 CPU (약 2.2GHz라고 생각합니다), 2GB RAM이 장착 된 4 세짜리 랩톱에서 테스트했습니다. BG RAM이 48 개인 경우 CPU 성능이 훨씬 더 뛰어납니다.
내가 한 것은 다음과 같이 100000 점으로 임의의 점 테이블을 만드는 것이 었습니다.
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;
그런 다음 다음과 같은 gid를 추가하십시오.
ALTER TABLE t ADD COLUMN GID SERIAL;
그런 다음 :
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);
약 62 초가 소요됩니다 (ArcGIS 결과와 동일한 양의 포인트 비교). 결과는 내 테이블 t의 포인트를 인구 조사가있는 테이블의 gid와 연결하는 테이블입니다.
이 속도로 약 34 시간 내에 200 밀 포인트를 수행합니다. 따라서 포인트 중 하나를 확인하는 것으로 충분하면 이전 랩톱이 하나의 코어로 수행 할 수 있습니다.
그러나 두 지점을 모두 확인해야 할 경우 더 어려울 수 있습니다.
따라서 db에 대해 여러 세션을 시작하고 다른 쿼리를 실행하여 둘 이상의 코어에 수동으로로드를 분배 할 수 있습니다.
50000 점과 두 개의 CPU 코어가있는 예에서 나는 시도했다.
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);
하나의 db-session에서 실행과 동시에
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);
다른 DB 세션에서.
약 36 초가 걸렸으므로 디스크 쓰기에 따라 첫 번째 예보다 약간 느립니다. 그러나 바이트 코어가 동시에 작동하기 때문에 36 초 이상 걸리지 않았습니다.
테이블 t1과 t2를 통합하려면 다음을 시도하십시오.
CREATE TABLE t3 AS
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
약 0.5 초를 사용합니다.
따라서 최신 하드웨어를 사용하고 많은 코어에 부하를 분산 시키면 실제 상황이 테스트 케이스보다 느리더라도 이것이 가능합니다.
예제는 Linux (Ubuntu)에서 나온 것입니다. Windows를 사용하는 것도 또 다른 이야기가 될 것입니다. 그러나 다른 모든 일상적인 응용 프로그램을 실행 중이므로 랩톱이 이전보다 상당히 많이로드되었습니다. 따라서 pgadmin 이외의 다른 것을 열지 않고도 Windows 사례를 잘 시뮬레이션 할 수 있습니다.