Tìm dòng gần nhất cho 2 điểm bằng PostGIS?


9

Tôi có một bảng t chứa một cột line_positionscó kiểu dòng. Cho 2 điểm tôi muốn tìm đường gần nhất đủ gần (dưới 10km) và đường đó không đi quá gần đến điểm tôi muốn tránh (tối thiểu 20km). Hiện tại tôi đang sử dụng

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

Có một chỉ số chính ix_path_line_positionstrên cột line_poseitions.

Nó hoạt động nhưng chậm, trong khoảng từ 3 đến 30 giây chỉ với 100000 hàng trong t.

giải thích phân tích cho:

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

Làm thế nào tôi có thể cải thiện nó? Thay vào đó, sử dụng tính toán hình học (nhưng theo dõi của tôi có thể kéo dài vài nghìn km, liệu khoảng cách tính toán có chính xác không)? Sử dụng toán tử <-> KNN (nhưng vì tôi đặt hàng trên tổng 2 khoảng cách, nên dường như không sử dụng chỉ số chính)?


Bạn có thể thử tăng tham số work_mem , trước khi thực thi mã. Ví dụ:SET work_mem TO '200MB';
Yaroslav

Câu trả lời:


1

Là hai điểm nhất định luôn trong phạm vi 10km của nhau. Nếu vậy, bạn có thể thử đặt hai điểm thành một dòng và thực hiện một ST_DWithin thay vì hai. Điều đó có thể cải thiện mọi thứ một chút.

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

Không, 2 điểm không cách nhau 10km, chúng có thể cách xa hàng ngàn km. Hạn chế là cả hai cách dòng dưới 10km, nhưng nó thực sự có thể ở rất xa vì các dòng kéo dài hàng ngàn km.
Go4It
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.