Jika Anda dapat membatasi jarak maksimum antara kota Anda dan posisi lokal Anda, manfaatkan fakta bahwa satu menit garis lintang (utara - selatan) adalah satu mil laut.
Letakkan indeks di tabel lintang Anda.
Jadikan diri Anda fungsi tersimpan haversine(lat1, lat2, long1, long2, unit) dari rumus haversine yang ditunjukkan dalam pertanyaan Anda. Lihat di bawah
Kemudian lakukan ini, dengan garis lintang, garis bujur, dan mykm.
SELECT *
from cities a
where :mylatitude >= a.latitude - :mykm/111.12
and :mylatitude <= a.latitude + :mykm/111.12
and haversine(:mylatitude,a.latitude,:mylongitude,a.longitude, 'KM') <= :mykm
order by haversine(:mylatitude,a.latitude,:mylongitude,a.longitude, 'KM')
Ini akan menggunakan kotak pembatas garis lintang untuk secara kasar mengesampingkan kota-kota yang terlalu jauh dari titik Anda. DBMS Anda akan menggunakan pemindaian rentang indeks pada indeks lintang Anda untuk dengan cepat memilih baris di tabel kota Anda yang layak dipertimbangkan. Kemudian ia akan menjalankan fungsi haversine Anda, fungsi dengan semua matematika sinus dan kosinus, hanya pada baris tersebut.
Saya menyarankan garis lintang karena jarak garis bujur di lapangan bervariasi dengan garis lintang.
Perhatikan ini mentah. Ini bagus untuk pencari toko, tetapi jangan menggunakannya jika Anda seorang insinyur sipil -- bumi memiliki bentuk elips dan ini menganggapnya melingkar.
(Maaf tentang angka ajaib 111,12. Itu adalah jumlah km dalam derajat lintang, yaitu dalam enam puluh mil laut.)
Lihat di sini untuk fungsi jarak yang bisa diterapkan.