Saya memiliki tabel t yang berisi kolom line_positions
yang bertipe baris. Diberikan 2 poin saya ingin menemukan garis terdekat yang cukup dekat (kurang dari 10km) dan yang tidak melewati terlalu dekat dengan titik yang ingin saya hindari (minimum 20km). Saat ini saya gunakan
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
Ada indeks inti ix_path_line_positions
pada kolom line_positions.
Ia bekerja tetapi lambat, antara 3s dan 30s untuk hanya 100000 baris di t.
jelaskan analisis memberi:
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
Bagaimana saya bisa memperbaikinya? Sebagai gantinya menggunakan perhitungan geometri (tetapi lintasan saya dapat menjangkau beberapa ribu km, apakah jarak yang dihitung akan benar)? Menggunakan <-> operator KNN (tapi karena saya memesan pada jumlah 2 jarak, sepertinya tidak menggunakan indeks inti sih)?
SET work_mem TO '200MB';
Jawaban:
Apakah dua poin yang diberikan selalu dalam jarak 10 km satu sama lain. Jika demikian, Anda bisa mencoba membuat dua poin menjadi satu baris dan melakukan satu ST_DWithin alih-alih dua. Itu mungkin sedikit memperbaiki keadaan.
sumber