PostGIS를 사용하여 2 점으로 가장 가까운 선을 찾으십니까?


9

line_positionsline 유형 의 열 이 포함 된 테이블 t가 있습니다 . 2 점이 주어지면 충분히 가깝고 (10km 미만) 가장 가까운 선을 찾고 싶습니다. 최소 한 20km를 피하고 싶습니다. 현재는

SELECT t.*
FROM path t
WHERE
  ST_DWithin(ST_GeographyFromText('Point(69.835 22.596)'), t.line_positions, 10000, FALSE)  AND
  ST_DWithin(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, 10000, false) AND
  NOT ST_DWithin(ST_GeographyFromText('Point(-79.804 9.141)'), t.line_positions, 20000, false)
ORDER BY
  ST_Distance(ST_GeographyFromText('Point(69.835 22.576)'), t.line_positions, false) +
  ST_Distance(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, false)
  ASC
LIMIT 1

ix_path_line_positionsline_positions 열에 요지 색인이 있습니다 .

t에서 100000 개의 행에 대해서만 3 초에서 30 초 사이에 작동하지만 느립니다.

설명 분석은 제공합니다 :

Limit  (cost=9.95..9.95 rows=1 width=1432) (actual time=21729.253..21729.254 rows=1 loops=1)
   ->  Sort  (cost=9.95..9.95 rows=1 width=1432) (actual time=21729.251..21729.251 rows=1 loops=1)
         Sort Key: ((_st_distance('0101000020E61000003D0AD7A370755140FA7E6ABC74933640'::geography, line_positions, '0'::double precision, false) + _st_distance('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography, line_positions, '0'::double precision, false)))
         Sort Method: top-N heapsort  Memory: 26kB"
         ->  Index Scan using ix_path_line_positions on path t  (cost=0.28..9.94 rows=1 width=1432) (actual time=93.490..21710.562 rows=690 loops=1)
           Index Cond: ((line_positions && '0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography) AND (line_positions && '0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography))
           Filter: (('0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography && _st_expand(line_positions, '10000'::double precision)) AND ('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography && _st_expand(line_positions, '10000'::double precision)) AND _st_dwithin('0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography, line_positions, '10000'::double precision, false) AND _st_dwithin('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography, line_positions, '10000'::double precision, false) AND ((NOT ('0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography && _st_expand(line_positions, '20000'::double precision))) OR (NOT (line_positions && '0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography)) OR (NOT _st_dwithin('0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography, line_positions, '20000'::double precision, false))))
           Rows Removed by Filter: 15365
Planning time: 0.491 ms
Execution time: 21729.321 ms

어떻게 개선 할 수 있습니까? 대신 기하학 계산을 사용하십시오 (그러나 내 트랙은 수천 킬로미터에 달할 수 있으며 계산 거리는 정확합니까?)? <-> KNN 연산자 사용 (그러나 2 거리의 합계를 주문하기 때문에 어쨌든 요지 색인을 사용하지 않는 것 같습니다)?


코드를 실행하기 전에 work_mem 매개 변수 를 늘리려 시도 할 수 있습니다 . 예SET work_mem TO '200MB';
Yaroslav

답변:


1

주어진 두 지점이 항상 서로 10km 이내에 있습니다. 그렇다면 두 점을 한 줄로 만들고 두 개 대신 ST_DWithin을 수행하십시오. 상황이 약간 개선 될 수 있습니다.

SELECT t.*
FROM path t
WHERE
  ST_DWithin(ST_GeomFromText('LINESTRING(69.835 22.596,69.856 22.519)'), t.line_positions, 10000, FALSE)  
  NOT ST_DWithin(ST_GeographyFromText('Point(-79.804 9.141)'), t.line_positions, 20000, false)
ORDER BY
  ST_Distance(ST_GeographyFromText('Point(69.835 22.576)'), t.line_positions, false) +
  ST_Distance(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, false)
  ASC
LIMIT 1

아니요, 2 포인트는 서로 10km 이내에 있지 않으며 수천 km 떨어져 있습니다. 제약 조건은 선에서 10km 미만 떨어져 있지만 선이 천 킬로미터에 달했기 때문에 실제로 멀리 떨어질 수 있다는 것입니다.
Go4It
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.