14

restaurant各行の緯度経度データを含むテーブルがあります。

指定された半径 (1 マイル、5 マイルなど) 内のすべてのレストランを検索するための検索を実行するクエリを作成する必要があります。

queryこの目的のために、次のものがあります。

***Parameters***

Longitude: -74.008680
Latitude: 40.711676
Radius: 1 mile

***Query***

SELECT *
FROM restaurant
WHERE (
POW( ( 69.1 * ( Longitude - -74.008680 ) * cos( 40.711676 / 57.3 ) ) , 2 ) + POW( ( 69.1 * ( Latitude - 40.711676 ) ) , 2 )
) < ( 1 *1 );

テーブルには約 23k 行あります。結果セットのサイズがおかしくなることがあります。たとえば、5.4 マイルの検索では 880 行が返され、5.5 マイルの検索では 21,000 行が返されます。

このテーブルには nyc のレストラン データが含まれているため、実際の分布は結果セットとは異なります。

質問: このクエリに問題はありますか?

DB: MySQL、経度: DECIMAL(10,6)、緯度: DECIMAL(10,6)

4

4 に答える 4

16

このクエリに何か問題がありますか?

私の意見では、WHERE 句は数学が関係しているため遅くなり、WHERE 句で関数を使用すると、データベースがインデックスを使用してクエリを高速化できなくなります。データベースを作成し、クエリを作成するたびに、すべての行で大円計算を実行します。

個人的には、探している範囲に等しい辺を持つ正方形の TopLeft と BottomRight の座標 (ピタゴラスを使用して大雑把に計算するだけでよい) を計算し、より複雑な WHERE 句テストを実行します。その緯度/経度の正方形内にあるレコード。

データベース内の緯度と経度のインデックスを使用して、クエリ

WHERE MyLat >= @MinLat AND MyLat <= @MaxLat
      AND MyLong >= @MinLong AND MyLong <= @MaxLong

非常に効率的でなければなりません

(私は特にMySQLについての知識はなく、MS SQLについてのみ知っていることに注意してください)

于 2009-11-13T16:43:33.823 に答える
3

SPATIAL検索を高速化するために、テーブルにインデックスを作成することをお勧めします。

これを行うにはPOINT、テーブルに列を追加します。

ALTER TABLE restaurant ADD coords POINT NOT NULL;

CREATE SPATIAL INDEX sx_restaurant_coords ON restaurant (coords);

SELECT  *
FROM    restaurant
WHERE   MBRContains(coords, LineString(Point(583734 - 1609, 4507223 - 1609), Point(583734 + 1609, 4507223 + 1609))
        AND GLength(LineString(Point(583734, 4507223), coords)) <= 1609

単一のゾーン内の座標coordsとして保存する必要があります。UTM

于 2009-11-13T16:23:26.523 に答える
0

ここに投稿した関数などを使用します。

次に、レストランにクエリを実行します。たとえば、半径 5 マイル以内のすべてのものを取得します。

select * from restaurants 
  where dbo.udf_Haversine(latitude, longitude, @lat, @long) < 5

これは、郵便番号データでうまく機能します。

于 2009-12-08T04:39:48.310 に答える