PostGIS ST_Intersects에서 성능 문제를 해결하는 방법?


9

postgis의 초보자이며 쿼리 성능에 문제가 있습니다.

이것은 내 쿼리 :

SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1 
WHERE ST_Intersects ( ST_GeomFromText('a multiypolygon geom goes here',4326),position) 
ORDER BY userid, timestamp desc

문제는 매우 큰 다각형 (단어 문서의 600 페이지 길이!)을 포함하는 다중 다각형이며 실행하는 데 2 ​​시간 이상이 걸렸습니다!

쿼리를 최적화하거나 다른 방법을 사용하는 방법이 있습니까?

도와 주셔서 감사합니다!

답변:


8

해야 할 일은 큰 다중 다각형을 단일 다각형 (ST_Dump 포함)으로 테이블에 넣고 색인을 작성하는 것입니다. 다음과 같은 것 :

CREATE TABLE big_polygon as
SELECT (ST_Dump( ST_GeomFromText('a multiypolygon geom goes here',4326))).geom as geom;

-- It is always great to put a primary key on the table
ALTER table big_polygon ADD Column gid serial PRIMARY KEY;

-- Create the index
CREATE INDEX idx_big_polygon_geom
on big_polygon
USING gist(geom);

-- To give the database some information about how the index looks
analyze big_polygon;

-- Then you go:
SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1, big polygon WHERE ST_Intersects ( big_polygon.geom,position) 
ORDER BY userid, timestamp desc;

몇 가지 이유로 더 빠릅니다.


이 훌륭한 답변에 대해 Nicklas에게 감사드립니다. 죄송합니다. 둘 이상의 다각형이 있고 이미 색인이있는 테이블에 저장되어 있다는 언급이 없습니다. 그러나 지오메트리 데이터를 직접 제공하는 것이 더 빠릅니다. 그러나 나는 당신이 제안하는 방식을 시도하지만 여전히 오랜 시간이 걸립니다! 다른 제안?
사라

@ 사라. 좋아, ST_Dump에서 제안한 것처럼 다중 지오메트리를 단일 지오메트리로 분할하려고 했습니까?
Nicklas Avén

우리는 몇 명의 사용자 위치에 대해 이야기하고 있습니까? 큰 다각형은 몇 개입니까? big_polygons_table의 SELECT ST_npoints (geom)에서 무엇을 얻습니까?
Nicklas Avén

죄송하지만 내 테이블에 대해 더 명확하게 설명하겠습니다. 약 230 행의 기하 열을 포함하는 table1이 있고 각 행에는 다중 다각형이 있습니다 (국가를 나타내므로 크기가 다양합니다) _geom col에 색인이 있습니다. 위치 열 (포인트), 타임 스탬프, 사용자 ID 및 ID (pk) 및 (위치, 타임 스탬프, 사용자 ID)를 사용하여 생성 된 3 개의 인덱스를 포함하는 Table2.이 테이블은 약 103496003 행입니다. 최대 ST_npoint 수는 1440430이고 최소 수는 16. 혼란스럽게해서 미안하지만 정말 도움이 필요합니다! 감사합니다
Sara

2

그것은 어떤 종류의 품질-필요한 정밀도에 달려 있습니다. http://postgis.net/docs/ST_Simplify.html 을 사용하여 다각형을 분명히 단순화 할 수 있습니다.

GIS 응용 프로그램을 개발하는 동안 자주 수행 한 작업은 데이터를 최소화하는 가장 좋은 방법에 대해 생각하는 것이 었습니다. 예 : 예를 들어 경계 상자 내의 다각형을 미리 선택하십시오. -줌 레벨에 따라 초정밀 결과 (st_simplify)가 필요하지 않습니다 ...

희망이 조금 도움이되었습니다!


빠른 답변 감사합니다. 내 문제는 결과가 매우 정확해야 하므로이 기능이 여기에 도움이되지 않는다고 생각합니다! 하지만 제안 해 주셔서 감사합니다
Sara

0

postgres 및 / 또는 sql 전문 기술에 따라 몇 가지 옵션이 있습니다.

  1. EXPLAIN 명령을 통해 쿼리를 분석하여 특정 병목 현상이 발생했는지 확인하십시오. 경고 : 때때로 EXPLAIN의 출력 을 이해 하기 어려울 수 있습니다

  2. table1에있는 도형의 대부분 또는 상당 부분이 다중 다각형을 교차 하지 않을 것으로 예상되는 경우 간단한 다각형에 대해 예비 조건을 적용하려고 시도 할 수 있습니다 (예 : 다중 배치를 작은 조각으로 끊음). 그 결과. 예는 아래를 참조하십시오.

  3. 경우와 CPU가 병목 인 경우에만 I (즉, 서버가 붙어 컴퓨팅 교차로입니다) 둔하게 당신이 더 크고, 더 빠르고, 더 강력한 CPU를 얻을이나 제안이 아마존의 EC2 떨어져 한 번 높은 CPU 인스턴스를 임대하고있을 때 그것을 파괴 끝난

항목 2에 대한 예제 쿼리 :

SELECT DISTINCT ON (st1.userid) st1.userid ,ST_AsText(st1.position), st1.timestamp  
FROM (
    select userid, position, timestamp from table1 
    WHERE ST_Intersects ( YOUR_MULTIPOL_BOUNDS_HERE,position)
) as st1 
WHERE ST_Intersects ( ST_GeomFromText('a multiypolygon geom goes     here',4326),st1.position) 
ORDER BY st1.userid, st1.timestamp desc

성능을 향상시키기 위해 부속 선택 st1 을 테이블로 임시로 구체화 하여 색인화 할 수 있습니다.

@Nicklas는 제안 2에 대한 예제가 도움이되지 않아야한다는 의견을 지적 할 권리가 있습니다. 그는 옳지 만 나도 (부분적으로) 옳다고 생각합니다.

실제로 지난 11 월 postgis ML에서 매우 유사한 질문이 제기 된 것 같습니다.

http://postgis.refractions.net/pipermail/postgis-users/2011-November/031344.html

그리고 실제로는 다각형을 분해하여 인덱스가 간단한 경계 검사에 의해 유발되는 허위 교차를 가장 효과적으로 필터링 할 수 있다는 제안이 나왔습니다.


제안 2는 인덱스가 수행하는 작업이므로 도움이되지 않아야합니다. 그래서 그 구조는 다시 한 번 똑같이 할 것입니다.
Nicklas Avén

@ NicklasAvén 당신 말이 맞아, 나는 대답을 수정했다
unicoletti

0

사용 ST_SubDivide()

Postgis 버전 2.2의 경우을 사용할 수 있습니다 ST_SubDivide.

ST_Subdivide — 세트에 지오메트리가 지정된 정점 수보다 많은 지오메트리 세트를 반환합니다.

setof geometry ST_Subdivide(geometry geom, integer max_vertices=256);

당신은 또한 할 수 있습니다

  • 임시 테이블을 사용하십시오
  • 인덱스

여기서는 ST_SubDivide다각형을 10 개 이하의 정점이있는 하위 다각형으로 세분화 하는 데 사용 합니다.

CREATE TEMP TABLE divided AS
SELECT ST_SubDivide(bigmultipolygon,10)::geometery AS t(geom);

CREATE INDEX divided_idx ON divided USING gist(geom);

그때

SELECT DISTINCT ON (userid) userid ,ST_AsText(position), timestamp  
FROM table1
JOIN divided AS d
  ON ST_Intersects( d.geom, position )
ORDER BY userid, timestamp desc;

위의 작업을 수행하지 않으면 반올림 오류가 발생합니다.

일반 튜닝

문서에서 성능 팁 섹션을 참조하십시오 . 적절하게 조정되어 있는지 확인하십시오. max_parallel_workers_per_gather병렬화를 활용하기 위해 올리는 것을 고려하십시오 (현재 기본값은 꺼짐).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.