update - windows postgresql postgis




PostGIS에서 K- 가장 가까운 네이버 쿼리 (4)

PostGIS에서 다음 Nearest Neighbor Query를 사용하고 있습니다.

SELECT g1.gid g2.gid FROM points as g1, polygons g2   
WHERE g1.gid <> g2.gid
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)
LIMIT k;

이제는 두 테이블 모두에서 the_geom 및 gid 열에 대한 인덱스를 만들었으므로이 쿼리는 공간 조인을 포함하는 다른 공간 쿼리보다 훨씬 많은 시간이 소요됩니다.

K- 가까운 이웃을 찾는 더 좋은 방법이 있습니까? PostGIS를 사용하고 있습니다.

기하학 열에 대한 색인을 만들었지 만 비정상적으로 오랜 시간이 걸리는 또 다른 쿼리는 다음과 같습니다.

select g1.gid , g2.gid from polygons as g1 , polygons as g2
where st_area(g1.the_geom) > st_area(g2.the_geom) ;

나는 이러한 쿼리가 요점 인덱스에 의해 도움이되지 않는다고 생각하지만, 왜 그런가?

반면이 쿼리는 다음과 같습니다.

select a.polyid , sum(length(b.the_geom)) from polygon as a , roads as b  
where st_intersects(a.the_geom , b.the_geom);

다각형이나 점 테이블보다 훨씬 크고 복잡한 공간 연산자가 포함 된 "도로"테이블을 포함 함에도 불구하고 잠시 후 결과를 반환합니다.



p 점과 g 다각형이 있다고 가정하면 원래 쿼리는 다음과 같습니다.

SELECT g1.gid, g2.gid FROM points as g1, polygons g2   
WHERE g1.gid <> g2.gid
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom)
LIMIT k;

pxg 집합에서 k 개의 가장 가까운 이웃을 반환합니다. 쿼리는 인덱스를 사용할 수 있지만 여전히 가장 작은 거리의 k 행을 찾기 위해 전체 pxg 세트를 정렬해야합니다. 당신이 원하는 것은 다음과 같습니다 :

SELECT g1.gid, 
      (SELECT g2.gid FROM polygons g2   
       --prevents you from finding every nearest neighbour twice
       WHERE g1.gid < g2.gid 
       --ORDER BY gid is erroneous if you want to limit by the distance
       ORDER BY ST_Distance(g1.the_geom,g2.the_geom)
       LIMIT k)
FROM points as g1;

문제에 대한 몇 가지 생각 :

st_distance와 st_area는 인덱스를 사용할 수 없습니다. 그 이유는 두 기능을 모두 "내 안에 있습니까?"와 같은 질문으로 축소 할 수 없기 때문입니다. 또는 "a와 b가 겹 칩니 까?". 더 구체적 : GIST 색인은 두 객체의 경계 상자에서만 작동 할 수 있습니다.

이것에 대한 더 자세한 정보는 postgis 매뉴얼 에서 st_distance를 사용한 예제와 쿼리가 어떻게 향상되어 성능이 향상 될 수 있는지 살펴볼 수 있습니다.

그러나 이것은 k- nearest-neighbor 문제를 해결하지 못합니다. 이를 위해서는 지금 쿼리의 성능을 향상시키는 방법을 모릅니다. 내가 볼 수있는 유일한 기회는 k 개의 가장 가까운 이웃이 항상 x 미터 아래의 거리에 있다고 가정하는 것입니다. 그런 다음 포스트 지스 매뉴얼에서와 같이 비슷한 접근법을 사용할 수 있습니다.

두 번째 쿼리가 약간 빨라질 수 있습니다. 현재 테이블에 행이있는 것처럼 테이블 1의 각 개체에 대한 영역을 계산합니다. 전략은 먼저 데이터를 조인 한 다음 해당 함수를 기반으로 선택합니다. 면적 계산을 현저하게 줄이면 면적을 미리 계산할 수 있습니다.

WITH polygonareas AS (
    SELECT gid, the_geom, st_area(the_geom) AS area
    FROM polygons
)
SELECT g1.gid, g2.gid
FROM polygonareas as g1 , polygonareas as g2 
WHERE g1.area > g2.area;

세 번째 쿼리는 경계 상자를 사용하여 크게 최적화 할 수 있습니다. 두 객체의 경계 상자가 겹치지 않으면 객체가 작동하지 않습니다. 이렇게하면 주어진 색인을 사용할 수 있으므로 성능이 크게 향상됩니다.


2011 년 9 월 말 이후 PostGIS는 ORDER BY 절에서 사용할 수있는 특수 연산자를 통해 색인 된 가장 가까운 이웃 쿼리를 지원했습니다.

SELECT name, gid
FROM geonames
ORDER BY geom <-> st_setsrid(st_makepoint(-90,40),4326)
LIMIT 10;

... geom-90,40 에 가장 가까운 10 개의 객체를 확장 가능한 방식으로 반환합니다. 몇 가지 세부 사항 (옵션 및주의 사항)이 발표 포스트에 있으며 , <-><#> 연산자의 사용 은 이제 공식 PostGIS 2.0 참조에 문서화되어 있습니다. (두 가지의 주요 차이점은 <-> 모양 중심선을 비교하고 <#> 경계선을 비교한다는 점입니다. 점에 차이가 없으며 다른 모양이 검색어에 적합한 것을 선택합니다.)





nearest-neighbor