都市と地域の位置との間の最大距離を制限できる場合は、緯度の1分(北-南)が1海里であるという事実を利用してください。
緯度テーブルにインデックスを付けます。
質問に示されている半正矢関数から、自分自身に半正矢関数(lat1、lat2、long1、long2、unit)のストアド関数を作成します。以下を参照
次に、mylatitude、mylongitude、および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')
これは、緯度の境界ボックスを使用して、ポイントから離れすぎている都市を大まかに除外します。 DBMSは、緯度インデックスのインデックス範囲スキャンを使用して、検討する価値のある都市テーブルの行をすばやく選択します。次に、それらの行でのみ、すべての正弦および余弦の数学を含む半正矢関数を実行します。
経度の地上距離は緯度によって異なるため、緯度をお勧めします。
これは粗雑であることに注意してください。店舗検索には問題ありませんが、土木技師の場合は使用しないでください。地球は楕円形であり、これは円形であると想定しています。
(111.12の魔法の数については申し訳ありません。これは、緯度の1度でのkm数、つまり60海里です。)
実行可能な距離関数については、こちらをご覧ください。
このMySQLストアド関数がクエリで計算を行うのとは異なる結果をもたらすのはなぜですか?