代码之家  ›  专栏  ›  技术社区  ›  Phill

MySQL在搜索半径内查找纬度/纬度+半径的行

  •  0
  • Phill  · 技术社区  · 10 年前

    有没有人知道如何进行查询,让用户指定他们的纬度lng和半径,然后搜索可能有大量纬度lng+半径的位置,看看是否有重叠,然后允许按距离排序?

    我们已经被要求允许公司在他们经营的郊区地图上放置标记,并能够绘制半径,但我在谷歌上找不到这样的查询。

    我目前正在使用以下查询,

    (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 回复  |  直到 10 年前
        1
  •  1
  •   Robbie    10 年前

    非常简单的答案:使用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);这减少了需要搜索的点数。然后在mySQL中检查x和y的实际差值是否在一个平方内,然后,一旦你大幅减少了它,就进行cos/sin计算。