我正在编写一个应用程序,需要允许用户选择位于某个半径范围内的元素。没有办法知道最终会有多少个位置,但可能会有数万个。进行搜索的用户是位置节点之一(而不仅仅是他们的手机提交的任意位置或诸如此类的东西)
我看到这样的答案:mysql lat lon calulation to show locations within radius但我担心这是一项非常严肃的事业,因为所涉及的数学计算需要针对每一个"其他"位置。
我正在考虑的另一种方法是建立一个关系表,用于标识每个位置之间的距离(每次添加位置时我都会填充),授予它将有大量行来定义每个可能的位置关系,但随后选择*该表将超快,特别是如果距离被索引。
很想从在mySQL中完成此操作的人那里得到一些建议,并且可以警告/建议我支持或反对最好的方法。
答案 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
是位置坐标。
查询在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秒
问题始终是:您需要计算多少个值?