基于纬度经度进行半径搜索的SQL查询

Pun*_*eet 12 mysql sql iphone geolocation latitude-longitude

我们有一个餐厅餐桌,每行有一个长期数据.

我们需要编写一个执行搜索的查询来查找所提供半径内的所有餐馆,例如1英里,5英里等.

我们为此目的提供以下查询:

***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 );
Run Code Online (Sandbox Code Playgroud)

该表有大约23,000行.结果集的大小有时很奇怪,例如,对于5.4英里的搜索,它返回880行,对于5.5英里,它返回21k行.

此表包含nyc的餐馆数据 - 因此实际分布不是根据结果集.

问题:是否有任何错误使用此查询?

DB:MySQL,经度:DECIMAL(10,6),纬度:DECIMAL(10,6)

Kri*_*ten 13

是否有任何错误使用此查询?

在我看来,由于所涉及的数学,WHERE子句将会很慢,并且在WHERE子句中使用函数将阻止数据库使用索引来加速查询 - 因此,实际上,您将检查数据库,并在每次进行查询时对每一行执行大圆数学运算.

就个人而言,我会计算一个正方形的TopLeft和BottomRight坐标(只需要用毕达哥拉斯进行粗略计算),其边长等于你要查找的范围,然后对较小的子集执行更复杂的WHERE子句测试.在Lat/Long方格内的记录.

使用数据库中的Lat&Long索引查询

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

应该非常有效率

(请注意,我不知道MySQL,只有MS SQL)


Qua*_*noi 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
Run Code Online (Sandbox Code Playgroud)

您应该将坐标存储coordsUTM单个区域内。