line_positions
行タイプの列を含むテーブルtがあります。2つのポイントを考えて、十分に近い(10 km未満)と、避けたいポイント(最小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_positions
line_positions列に要旨インデックスがあります。
それは動作しますが、3秒から30秒の間で、tの100,000行だけで遅くなります。
分析は与える説明:
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
どうすれば改善できますか?代わりにジオメトリ計算を使用します(ただし、私のトラックは数千kmにわたる可能性があります。計算された距離は正しくなりますか?)<-> KNN演算子を使用しています(ただし、2つの距離の合計で注文しているため、とにかく要点インデックスを使用していないようです)?
SET work_mem TO '200MB';