더 큰 OSM 추출을 처리하기에 Hstore 키 / 값과 공간 쿼리를 너무 느리게 결합


13

PostgreSQL 9.3.5 및 PostGIS 2.1.4를 사용하여 OSM 데이터에 대한 일부 통계를 계산하려고합니다. Geofabrik에서 다운로드 한 작은 바바리아 추출물로 시작했습니다. db 스키마는 일반적인 API 0.6 스키마이며 덤프 접근 방식을 통해 Postgres로 데이터를 가져 왔습니다 (osmosis와 함께 제공되는 pgsnapshot_schema_0.6 * .sql 스크립트 사용). 진공 분석도 수행되었습니다.

내가 사용하는 유일한 사용자 정의 작업은 모든 관리 경계 관계에 대한 다중 다각형을 포함하는 다각형 테이블입니다. 다각형 지오메트리는 어떤 식으로도 단순화되지 않았습니다.

내가 지금 달성하려는 것은 바이에른의 admin = 6 경계 안에있는 모든 노드를 계산하는 것입니다. 내 SQL 쿼리는 다음과 같습니다.

SELECT relpoly.id, count(node) 
FROM bavaria.relpolygons relpoly, bavaria.nodes node
WHERE relpoly.tags @> '"boundary"=>"administrative","admin_level"=>"6"'::hstore 
AND ST_Intersects(relpoly.geom, node.geom)
GROUP BY relpoly.id;

Postgres가 중첩 루프 조인을 수행하고 모든 admin = 6 경계에 대해 모든 노드를 스캔하기 때문에이 쿼리의 런타임은 끔찍합니다. 참고로, 바바리아는 98 admin = 6 폴리곤으로 나뉘며 바바리아 추출물에는 약 3 천만 개의 노드가 있습니다.

이 차선의 쿼리 실행을 피하고 Postgres에게 모든 노드를 한 번만 스캔해야한다고 말할 수 있습니까 (예 : 결과 세트에서 해당 다각형에 대한 카운터를 증가 시키거나 힌트를 사용하여)?

편집하다:

1) 바바리아 노드에 공간 인덱스가 존재합니다.

CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);

2) 쿼리 계획은 다음과 같습니다.

HashAggregate  (cost=284908.49..284908.75 rows=26 width=103)
  ->  Nested Loop  (cost=111.27..283900.80 rows=201537 width=103)
        ->  Bitmap Heap Scan on relpolygons relpoly  (cost=4.48..102.29 rows=26 width=5886)
              Recheck Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
              ->  Bitmap Index Scan on relpolygons_geom_tags  (cost=0.00..4.47 rows=26 width=0)
                    Index Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
        ->  Bitmap Heap Scan on nodes node  (cost=106.79..10905.50 rows=983 width=127)
              Recheck Cond: (relpoly.geom && geom)
              Filter: _st_intersects(relpoly.geom, geom)
              ->  Bitmap Index Scan on idx_nodes_geom  (cost=0.00..106.55 rows=2950 width=0)
                    Index Cond: (relpoly.geom && geom)

삼)

다음 두 인덱스를 만들었지 만 쿼리 계획 및 런타임이 변경되지 않았습니다.

CREATE INDEX relpolygons_tags_boundary on bavaria.relpolygons( (tags->'boundary') );
CREATE INDEX relpolygons_tags_admin on bavaria.relpolygons( (tags->'admin_level') );
ANALYZE bavaria.relpolygons;

1
bavaria.nodes에 공간 인덱스가 있습니까?
user30184

예, 질문을 편집하고 노드 및 쿼리 계획에 대한 인덱스에 대한 정보를 제공했습니다
Alf Kortig

3
두 가지 옵션이 있습니다. 1-hstore 태그에 대한 색인을 추가하십시오. 2-쿼리에 사용중인 태그 ( boundaryadmin_level)를 테이블의 추가 열로 추출하여 직접 사용하십시오.
BradHards

편집 (3)을 참조하십시오. 두 개의 인덱스가 추가되었지만 쿼리 계획이나 런타임에는 변경되지 않았습니다.
Alf Kortig

일부 테스트 후 (3)에서 올바른 색인을 만들 었는지 더 이상 확실하지 않습니다. 지금까지-> 및?에 대한 색인을 만들었습니다. hstore 연산자. 그러나 내 쿼리에 @>를 사용하고 있습니다.
Alf Kortig

답변:


5

hstore 태그를 색인화하는 가장 좋은 방법 은 문서 에서 @>,?,? & 및? |를 지원하는 GIN 또는 GIST 색인을 사용하는 것입니다 . operator , 즉 키와 키 / 값 쌍을 검색합니다. 함수를 사용하여 B- 트리 인덱스의 태그를 추출하는 방법은 합리적이지만 특정 키 / 값 쌍도 확인하고 있기 때문에 분석기는 전체 테이블 스캔을 선택했습니다.

bavaria.relpolygons에 액세스 할 수는 없지만 속도 제한 및 고속도로 태그에 대한 OSM UK의 유사한 쿼리를 기반으로 다음 쿼리에 대한 설명을 위해이 정보를 얻습니다.

SELECT count(*) 
 FROM ways 
WHERE tags @> 'highway=>motorway'::hstore 
 AND tags @> 'maxspeed=>"50 mph"'::hstore;


Aggregate  (cost=48.66..48.67 rows=1 width=0)
    ->  Index Scan using ix_ways_tags_gist on ways  (cost=0.42..48.64 rows=11 width=0)
     Index Cond: ((tags @> '"highway"=>"motorway"'::hstore) AND (tags @> '"maxspeed"=>"50 mph"'::hstore))

1000 만 개의 행이있는 테이블의 경우 직접 인덱스 스캔 (gist 인덱스 사용)을 보여줍니다. 색인은 다음과 같이 단순하게 작성되었습니다.

CREATE INDEX ix_ways_tags_gist ON ways USING gist (tags);

공간 상태를 확인할 수는 없지만, 선택적인 것보다 덜 선택적이라고 생각합니다

relpoly.tags @> ' "boundary"=> "administrative", "admin_level"=> "6"':: hstore.

따라서 재확인 조건에만 사용됩니다.

GIN 지수와 GIST 지수의 차이에 대해서도 이처럼 훌륭한 해답 이 있습니다 . 일반적인 발견은 GIN 색인이 더 크고 느리게 구축되지만 텍스트 검색 문제에서 훨씬 빠르다는 것입니다.

너무 늦게 답변을 드려 죄송합니다. 최근 OSM 및 hstore에서 유사한 작업을 수행하고 있으며 한 번이 질문에 별표를 표시했을뿐만 아니라 이제 답변 할 수 있음을 발견했습니다 .D.

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