Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

perhitungan jarak dalam kueri mysql

Opsi 1:Lakukan perhitungan pada database dengan beralih ke database yang mendukung GeoIP.

Opsi 2:Lakukan perhitungan pada database menggunakan prosedur tersimpan seperti ini:

CREATE FUNCTION calcDistance (latA double, lonA double, latB double, LonB double)
    RETURNS double DETERMINISTIC
BEGIN
    SET @RlatA = radians(latA);
    SET @RlonA = radians(lonA);
    SET @RlatB = radians(latB);
    SET @RlonB = radians(LonB);
    SET @deltaLat = @RlatA - @RlatB;
    SET @deltaLon = @RlonA - @RlonB;
    SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
    COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
    RETURN 2 * ASIN(SQRT(@d)) * 6371.01;
END//

Jika Anda memiliki indeks pada garis lintang dan garis bujur dalam database Anda, Anda dapat mengurangi jumlah perhitungan yang perlu dihitung dengan mengerjakan kotak pembatas awal di PHP ($minLat, $maxLat, $minLong dan $maxLong), dan membatasi baris ke subset entri Anda berdasarkan itu (WHERE garis lintang ANTARA $minLat DAN $maxLat DAN garis bujur ANTARA $minLong AND $maxLong). Kemudian MySQL hanya perlu menjalankan perhitungan jarak untuk subset baris tersebut.

Jika Anda hanya menggunakan prosedur tersimpan untuk menghitung jarak) maka SQL masih harus memeriksa setiap catatan dalam database Anda, dan untuk menghitung jarak untuk setiap catatan dalam database Anda sebelum dapat memutuskan apakah akan mengembalikan baris itu atau membuangnya .

Karena perhitungannya relatif lambat untuk dieksekusi, akan lebih baik jika Anda dapat mengurangi kumpulan baris yang perlu dihitung, menghilangkan baris yang jelas-jelas akan berada di luar jarak yang diperlukan, sehingga kita hanya menjalankan perhitungan yang mahal untuk jumlah baris yang lebih sedikit.

Jika Anda menganggap bahwa yang Anda lakukan pada dasarnya adalah menggambar lingkaran di peta, berpusat pada titik awal Anda, dan dengan radius jarak; maka rumus tersebut hanya mengidentifikasi baris mana yang termasuk dalam lingkaran itu... tetapi masih harus memeriksa setiap baris.

Menggunakan kotak pembatas seperti menggambar persegi di peta terlebih dahulu dengan tepi kiri, kanan, atas dan bawah pada jarak yang sesuai dari titik pusat kita. Lingkaran kita kemudian akan digambar di dalam kotak itu, dengan titik Paling Utara, Paling Timur, Paling Selatan dan Barat pada lingkaran yang menyentuh batas kotak. Beberapa baris akan berada di luar kotak itu, jadi SQL bahkan tidak repot-repot mencoba menghitung jarak untuk baris tersebut. Ini hanya menghitung jarak untuk baris-baris yang termasuk dalam kotak pembatas untuk melihat apakah mereka juga termasuk dalam lingkaran.

Di dalam PHP Anda (kira Anda menjalankan PHP dari nama variabel $), kami dapat menggunakan perhitungan yang sangat sederhana yang menghitung garis lintang dan garis bujur minimum dan maksimum berdasarkan jarak kami, kemudian menetapkan nilai-nilai tersebut dalam klausa WHERE dari SQL Anda penyataan. Ini adalah kotak kami secara efektif, dan apa pun yang berada di luar kotak tersebut secara otomatis dibuang tanpa perlu menghitung jaraknya.

Ada penjelasan yang bagus tentang ini (dengan kode PHP) di Movable Type situs web yang harus menjadi bacaan penting bagi siapa saja yang berencana untuk melakukan pekerjaan GeoPositioning di PHP.

EDIT Nilai 6371,01 dalam prosedur tersimpan calcDistance adalah pengali untuk memberi Anda hasil yang dikembalikan dalam kilometer. Gunakan pengganda alternatif yang sesuai jika Anda ingin menghasilkan mil, mil laut, meter, apa pun



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ambil Gambar yang disimpan sebagai BLOB pada MYSQL DB

  2. Database Resep, cari berdasarkan bahan

  3. Peringatan:mysqli_stmt::bind_param():Jumlah variabel tidak cocok dengan jumlah parameter dalam pernyataan yang disiapkan

  4. Jumlah koneksi yang optimal di kumpulan koneksi

  5. Bagaimana cara memeriksa apakah suatu variabel NULL, lalu mengaturnya dengan prosedur tersimpan MySQL?