私は、指定された場所からある範囲(マイル)内のすべての場所を見つけることを可能にするクエリを書く必要があります。2つの座標の間の距離ですが、これを単純化したり、別の手法を使用するにはどうしたらいいですか?
id | name | lat | lng
だから私は研究をやって発見されています:this my sql presentation
私は約100行でテーブルの上にそれをテストしているし、もっとたくさんを持っています
表には、このようなものです! - スケーラブルでなければならない。これはかなり良いです、その周り50msので行を返さ
//just some test data this would be required by user input
set @orig_lat=55.857807; set @orig_lng=-4.242511; set @dist=10;
SELECT *, 3956 * 2 * ASIN(
SQRT(POWER(SIN((orig.lat - abs(dest.lat)) * pi()/180/2), 2)
+ COS(orig.lat * pi()/180) * COS(abs(dest.lat) * pi()/180)
* POWER(SIN((orig.lng - dest.lng) * pi()/180/2), 2)))
AS distance
FROM locations dest, locations orig
WHERE orig.id = '1'
HAVING distance < 1
ORDER BY distance;
:
は、私はこの最初のような、よりシンプルなものを試してみました! しかし、これは行が増えるにつれて劇的に減速します。
EXPLAIN
は、明白なPRIMARYキーを使用していることを示しています。
次に、記事linked aboveを読んだ後。このクエリの時間が、これはあまりにも悪いの周り240msではありませんが、最後のよりも遅いです
// defining variables - this when made into a stored procedure will call
// the values with a SELECT query.
set @mylon = -4.242511;
set @mylat = 55.857807;
set @dist = 0.5;
-- calculate lon and lat for the rectangle:
set @lon1 = @[email protected]/abs(cos(radians(@mylat))*69);
set @lon2 = @[email protected]/abs(cos(radians(@mylat))*69);
set @lat1 = @mylat-(@dist/69);
set @lat2 = @mylat+(@dist/69);
-- run the query:
SELECT *, 3956 * 2 * ASIN(
SQRT(POWER(SIN((@mylat - abs(dest.lat)) * pi()/180/2) ,2)
+ COS(@mylat * pi()/180) * COS(abs(dest.lat) * pi()/180)
* POWER(SIN((@mylon - dest.lng) * pi()/180/2), 2)))
AS distance
FROM locations dest
WHERE dest.lng BETWEEN @lon1 AND @lon2
AND dest.lat BETWEEN @lat1 AND @lat2
HAVING distance < @dist
ORDER BY distance;
:私はこのような何かを試してみました。しかし、これはもっと速く動くはずのはるかに多くの行で想像することができます。ただし、EXPLAIN
はlat
,lng
またはPRIMARY
という可能なキーを表示し、PRIMARY
を使用しています。
どうすればよいですか?
私はPOINT()として緯度経度を格納できると知っています。しかし、私はまた、これが高速か正確かを示すあまりにも多くのドキュメントを見つけられませんでしたか?
その他のアイデアは喜んで受け入れられるでしょう!
ありがとうございました!
-Stefan
UPDATE:ジョナサンレフラーが指摘したように
私は気づいていなかったいくつかのミス作った:
私は腹筋を入れていたが() lat値の1つに設定します。私は必要がなかったときにも、2番目のWHERE句でID検索を使用していました。最初のクエリでは、純粋に実験的なものでしたが、2番目のクエリは生産を打つ可能性が高いです。これらの変更EXPLAIN
後
キーは現在の周り180ms今改善している応答するlng
カラムと平均時間を使用して示しています。
私はこのような何かをしたいと思っています。最終的なストアドプロシージャを投稿できますか?私は前にストアドプロシージャを書いたことはありません。最初の質問には、静的なパラメータがあるようなコードがあります。myLat、myLon、および距離をストアドプロシージャに渡すにはどうすればいいですか?距離" – erik