2

ユーザーが自分の場所の半径内にある要素を選択できるようにする必要があるアプリを作成しています。最終的に何カ所になるかはわかりませんが、数万カ所になる可能性があります。検索を行うユーザーはロケーション ノードの 1 つです (電話などで送信された任意の位置だけではありません)。

次のような回答が表示されます:半径内の場所を表示するためのmysql lat lon calulationですが、関連する数学を「他の」場所ごとに計算する必要があることを考えると、これは非常に深刻な作業であると懸念しています。

私が検討していたもう 1 つのアプローチは、各場所間の距離を識別するリレーショナル テーブル (場所が追加されるたびにデータを入力する) を用意することです。 *に対して、特に距離がインデックス化されている場合、そのテーブルは超高速になります。

mySQL でこれを行ったことがあり、最良のアプローチに賛成または反対することを警告/アドバイスできる人からアドバイスをもらいたいです。

4

3 に答える 3

2

次の SQL クエリは、球面余弦法則を使用して、テーブル内の座標と座標の間の距離を計算します。結果を 10 に制限し、距離で並べ替えます。これは、MySQL で実行するには複雑すぎる Haversine Formula の代わりに使用されます。

余弦の球面法則

ここで、R = 3,959 マイルまたは 6,371 km

d = acos( sin(lat1).sin(lat2) + cos(lat1).cos(lat2).cos(lng2-lng1) ).R

SQL

SELECT  name, lat, lng, ( 3959 * acos( cos( radians($center_lat) ) 
                        * cos( radians( lat ) ) * cos( radians( lng )
                        - radians($center_lng) ) + sin( radians($center_lat) ) 
                        * sin( radians( lat ) ) ) ) AS distance FROM table 
                        ORDER BY distance LIMIT 0 , 10

$center_lat&$center_lngは場所の座標です。

クエリはSQL 数学関数を使用します

クエリは、50,068 行のデータベースで 0.2506 秒かかりました

MySQL で利用可能な空間関数は、あなたの目的には適していません。このブログを参照してください。

于 2014-10-24T11:22:27.510 に答える
1

GIS は半径距離の開始には適していますが、最終的には (縮尺) 緯度/経度グリッドまで解決する必要があります。半径は、グリッドの保存と検索が非常に簡単な場所で計算するのにコストがかかります。私の経験では、MySQL の FWIW GIS 機能は、5.6 より前の多くのコア (10+) ではうまくスケーリングされず、5.7 まで修正されない可能性があります。

于 2014-10-24T04:20:46.657 に答える
0

実際に必要なデータの一部を事前に計算してデータベースに保存すると、そのデータに基づいて計算を行うのが非常に高速になります。

この質問の私の答えから:

SOでの郵便番号近接質問の並べ替え

次のような計算を使用できます

$iRadius * 2 * ASIN(SQRT(POWER(SIN(( $fLat - abs(pos.lat)) * pi() / 180 / 2),2) +
COS( $fLat * pi()/180) * COS(abs(pos.lat) * pi() / 180) * POWER(SIN(( $fLon - pos.lon) *
pi() / 180 / 2), 2) )) AS distance

実際の数学関数の負荷を事前に計算し、データベースに保存することもできます。これにより、クエリの速度が向上します。

また、特定の半径のみに関心があることがわかっている場合は、差が大きい緯度/経度の値を無視することもできます (特定の距離があることをすでに意味しているため)。あなたの場所からの特定の範囲。

このアプローチを使用して、0.1 秒未満で郵便番号 (>60.000) までの距離を計算しました

問題は常に次のとおりです。いくつの値に対して計算する必要がありますか?

于 2014-10-24T06:05:12.967 に答える