在mySQL中测量半径内位置的正确方法是什么?

时间:2014-10-24 03:51:16

标签: mysql geolocation hamming-distance

我正在编写一个应用程序,需要允许用户选择位于某个半径范围内的元素。没有办法知道最终会有多少个位置,但可能会有数万个。进行搜索的用户是位置节点之一(而不仅仅是他们的手机提交的任意位置或诸如此类的东西)

我看到这样的答案:mysql lat lon calulation to show locations within radius但我担心这是一项非常严肃的事业,因为所涉及的数学计算需要针对每一个"其他"位置。

我正在考虑的另一种方法是建立一个关系表,用于标识每个位置之间的距离(每次添加位置时我都会填充),授予它将有大量行来定义每个可能的位置关系,但随后选择*该表将超快,特别是如果距离被索引。

很想从在mySQL中完成此操作的人那里得到一些建议,并且可以警告/建议我支持或反对最好的方法。

3 个答案:

答案 0 :(得分:1)

GIS是一个开始半径距离的好地方,但最终(比例)你必须分解为纬度/长度网格。计算网格非常容易存储和查找的半径是很昂贵的。根据我的经验,MySQL中的FWIW GIS功能在5.6之前的许多核心(10+)上不能很好地扩展,并且可能直到5.7才能修复。

答案 1 :(得分:1)

以下SQL查询使用Spherical Law of Cosines来计算表中坐标和坐标之间的距离。它将结果限制为10并按距离排序。这用来代替Haversine公式,它太复杂了,不能用MySQL执行

余弦球面定律

其中R = 3,959英里或6,371公里

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&amp; $center_lng是位置坐标。

查询使用SQL Math functions

查询在50,068行的数据库上花了0.2506秒

MySQL中可用的空间函数不适合您的参与请参阅Blog

答案 2 :(得分:0)

如果您预先计算了实际需要的一些数据并将其存储在数据库中,那么根据该数据进行一些计算应该非常快。

从我在这个问题中的答案:

Sorting zip code proximity question on 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

其中可以预先计算实际数学函数的负载并将其存储在数据库中。这可以帮助您加快查询速度。

如果你知道你只对特定半径感兴趣,你甚至可以忽略具有更大差异的纬度/经度值(因为这已经意味着它们具有特定的距离),所以你只能计算lat / lon您所在位置的特定范围内的值。

我使用这种方法来计算邮政编码的距离(> 60.000),低于0.1秒

问题始终是:您需要计算多少个值?