0

私はMySQLとデータベース全般に非常に慣れていませんが、長い時間がかかるように思われるクエリがあります。緯度と経度の座標を使用して、別の場所から5マイル以内にある約700,000の場所データベースから場所を見つけています。問題は、クエリに2.12秒かかることです。トラフィックを取得し始めると、MySQLがジャムするのではないかと心配しています。これが私のコードです:

SELECT *,((ACOS(SIN(44.4726 * PI() / 180) * SIN(lat * PI() / 180) + COS(44.4726 * PI() /          180) * COS(lat * PI() / 180) * COS((-93.1785 - lon) * PI() / 180)) * 180 / PI()) * 60 *   1.1515) AS distance FROM locations HAVING distance<=5 ORDER BY distance ASC LIMIT 30;

latフィールドとlonフィールドにインデックスを付けていますが、それでも長い時間がかかります。これは、サーバーに要求していることで予想されることですか?追加してスピードアップできますか

WHERE state = "$state"

もしそうなら、私はそれをSelectのどこに追加しますか?

4

3 に答える 3

1

計算値(距離)から派生しないフィルターが実際にはないため、このクエリはテーブル全体をseqスキャンします。インデックス付きの列でフィルタリングするwhere句を追加すると、オーバーヘッドを確実に排除できますが、テーブルの代わりにインデックスを使用することを保証するのに十分なデータがテーブルにあるとDBが判断した場合に限ります。したがって、必ずそれも分析してください。

クエリに距離があるロジックは非常に醜いですが、テーブルから選択するたびに700k以上の行をネットワーク経由で送信したくない理由がわかります。空間計算を行っているようで、空間データ型とインデックスを調査するのが賢明かもしれません。

エド:また、where句についてのあなたの質問...

select fields [aggregate fields]
from table
where where clause
group by fields
having having clause
于 2012-05-30T05:11:40.923 に答える
0

なぜクエリで計算を行うのですか?そのようなロジックはDALに含めるべきではありません。

必要な列だけを取得してから、コードで計算を実行することをお勧めします。これにより、latとlongのない部分のみを計算できます(たとえば、SIN(44.4726 * PI()/ 180))。結果をループし、必要に応じてlatとlongを追加します。

于 2012-05-30T05:05:51.080 に答える
0

このタイプのクエリが通常どのように行われるかについては何も知りませんので、私の提案は無視してください。ただし、アプリケーションが入力{lat、lon}を取得し、各方向(北、東、南と西)。次に、クエリは、上限と下限の間にlatとlongを持つレコードのみを選択できます。

それでも距離の計算を行う必要がありますが、一致する可能性のないレコードが削除されるため、クエリのオーバーヘッドを減らす必要があります。さらに、latとlongにインデックスがある場合、mysqlはこれらを使用できるはずです。

私が言うように、私はその領域での経験がないので、ジオメトリを誤解したかもしれませんが、他の提案に加えて、それは有用な最適化かもしれません。

于 2012-05-30T10:48:52.043 に答える