Saya memiliki dua set pengukuran bumi dari data satelit, masing-masing dengan bidang waktu (mjd untuk tanggal julian rata-rata) dan posisi geografi (GeoPoint, spasi) dan saya mencari kebetulan di antara dua set sehingga waktu mereka cocok dengan ambang batas 3 jam (atau 0,125 hari) dan jaraknya dalam jarak 200 km.
Saya telah membuat indeks untuk bidang mjd di kedua tabel dan tabel spasial.
Ketika saya baru saja bergabung dengan batasan waktu, basis data menghitung 100.000 kecocokan dalam 8 detik dan menghitung jarak untuk semua 100.000 kecocokan pada waktu itu. Kueri terlihat seperti ini:
select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )
Dan rencana yang dijalankan adalah:
Saat disortir, 9 jaraknya berada di bawah 200km, jadi ada yang cocok. Masalahnya adalah, ketika saya menambahkan batasan jarak dan menjalankan ini sebagai gantinya,
select top 10 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
and h.GeoPoint.STDistance(m.GeoPoint)<200000
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )
itu hilang untuk waktu yang lama. Jelas, dalam 8 detik, dapat menemukan 100.000 pertandingan yang sesuai, 9 di antaranya berada di bawah 200 km, sehingga pengoptimal harus mencoba sesuatu yang kurang optimal. Rencananya terlihat mirip dengan di atas dengan filter pada jarak (saya menduga).
Saya bisa memaksakan penggunaan indeks spasial dengan ini:
select top 5 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.GeoPoint.STDistance(m.GeoPoint)<200000
and h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD), index(ix_GeoPoint) ), table hint( m, index(ix_MJD) ) )
yang kemudian membutuhkan 3 menit untuk menemukan 5 pertandingan.
Bagaimana saya memberi tahu pengoptimal kueri untuk menggunakan pencarian indeks MJD pertama, dan kemudian indeks spasial kedua (atau apakah itu yang sudah dilakukannya) dan apakah ada cara saya dapat membantu dengan memberi tahu berapa banyak kecocokan yang diharapkan? Jika ia dapat menghitung 100.000 pertandingan dengan jarak dalam 8 detik yang memiliki 9 di bawah 200km, bukankah seharusnya penambahan indeks spasial membuatnya lebih cepat, bukan lebih lambat?
Terima kasih atas kiat atau ide lain.
EDIT: Untuk menjawab pertanyaan seperti apa rencana itu tanpa petunjuk, ini (dan ini akan berlangsung selamanya):
Mungkin juga layak disebutkan bahwa ada hampir 1 juta catatan di satu meja dan 8 juta di yang lain
sumber
Jawaban:
Masalahnya adalah bahwa ia mungkin (dan mengetahui indeks spasial, mungkin akan) menganggap bahwa filter spasial akan jauh lebih selektif daripada filter waktu.
Tetapi jika Anda memiliki beberapa juta catatan dalam jarak 200 km, maka itu bisa menjadi jauh lebih buruk.
Anda memintanya untuk menemukan catatan dalam jarak 200 km, yang mengembalikan data yang dipesan oleh beberapa tata ruang. Menemukan catatan di sana yang mendekati waktu berarti memeriksa masing-masing.
Atau Anda akan menemukan catatan berdasarkan waktu, dan Anda mendapatkan hasil dalam urutan waktu. Kemudian, memfilter daftar ini ke radius 200 km adalah masalah memeriksa masing-masing.
Jika Anda memfilter data dalam dua rentang seperti ini, menjadi sulit untuk menerapkan filter kedua menggunakan indeks. Anda mungkin lebih baik mengatakannya untuk tidak menggunakan indeks spasial jika filter waktu lebih ketat.
Jika keduanya besar secara individual, dan itu hanya bersama-sama bahwa mereka ketat, maka Anda memiliki masalah yang lebih kompleks, yang orang telah mencoba untuk memecahkannya untuk waktu yang lama, dan yang bisa diselesaikan dengan baik oleh indeks yang mencakup 3D (dan seterusnya) ruang. Kecuali SQL Server tidak memilikinya.
Maaf.
Edit: info lebih lanjut ...
Ini adalah masalah yang mirip dengan menemukan rentang waktu yang mencakup titik waktu tertentu. Saat Anda mencari catatan yang dimulai sebelum titik itu, Anda kemudian memiliki kekacauan akhir zaman yang tidak teratur - dan sebaliknya. Jika Anda mencari orang-orang di buku telepon yang nama keluarganya dimulai dengan F, Anda tidak bisa berharap menemukan orang-orang yang nama depannya dimulai dengan R dengan sangat mudah. Dan indeks pada nama depan juga tidak membantu karena alasan yang sama. Menemukan hal-hal dalam indeks berikutnya sulit ketika indeks pertama Anda bukan persamaan.
Sekarang, jika Anda dapat mengubah filter tanggal menjadi filter kesetaraan (atau serangkaian filter kesetaraan), maka Anda dapat mengambil risiko, kecuali bahwa indeks spasial adalah jenis indeks khusus dan tidak dapat digunakan sebagai tingkat kedua dalam indeks komposit.
Jadi Anda ditinggal dengan situasi yang canggung, saya khawatir. :(
Sunting: Coba:
Perhatikan bahwa saya sengaja melanggar sargability dengan membaginya dengan 1000 sebelum membandingkan dengan 200. Saya ingin pekerjaan ini dilakukan dalam Pencarian Kunci.
Pikiran Anda, Anda bisa menghindari kebutuhan untuk pencarian (dan petunjuk) dengan TERMASUK GeoPoint dan Waktu di kedua indeks ix_MJD. Itu pasti akan mengambil beberapa panas dari rencana permintaan.
sumber
select top 10000 h.Time, m.Time, m.GeoPoint.STDistance(h.GeoPoint), h.mjd-m.mjd from L2V5.dbo.header h join L2.dbo.MLS_Header m on m.GeoPoint.STDistance(h.GeoPoint)<200000 and m.mjd between h.mjd-.125 and h.mjd+.125 order by h.mjd