MySQL在搜索半径内查找具有lat / lng + radius的行

时间:2014-09-12 07:09:18

标签: php sql search location radius

有没有人知道怎么做一个查询,允许用户指定他们的纬度/经度和半径,然后搜索可能是一个非常大量的位置,也有一个lat lng +一个半径,看看是否任何重叠,然后允许按距离排序?

我们被要求允许公司在他们经营的郊区地图上放置标记,并且能够做半径,但我无法在Google上找到任何查询。

我目前正在使用以下查询来完成这项工作,

(SELECT ( 6371.01 * acos( cos( radians( $lat ) ) * cos( radians( location.lat ) ) 
 cos( radians( location.lng ) - radians( $lng ) )
 sin( radians( $lat ) ) * sin( radians( location.lat ) ) ) ) AS distance
FROM location 
HAVING distance <= $radius 
ORDER BY distance ASC) as distance

但显然这不允许位置具有半径。

这个问题的第二部分,这个搜索查询已经是一个非常大的查询的一部分..是否有任何关于优化这个的建议?每次我谷歌搜索上述查询的例子时,总会有人警告这个查询有多昂贵。目前,我能想到的唯一解决方案是拥有一个单独的搜索服务器。

1 个答案:

答案 0 :(得分:1)

非常简单的答案:在mySQL(http://dev.mysql.com/doc/refman/5.5/en/spatial-extensions.html

中使用空间几何函数

这些已经存在了一段时间,但在5.6中得到了很好的升级,这将使您更容易进行选择。 http://www.percona.com/blog/2013/10/21/using-the-new-spatial-functions-in-mysql-5-6-for-geo-enabled-applications/有一些细节。

如果您没有5.6则使用“网格”系统。基本上,当您存储点(x,y)时,还会存储覆盖较大正方形的网格标识符(X,Y)。当搜索附近的其他点时,你知道它在网格内(X-1到X + 1)和(Y-1到Y + 1);这会减少您需要搜索的点数。然后检查x和y的实际差异是否在mySQL中的一个平方内,然后,一旦你大量减少了它,那么就做你的cos / sin数学。