如何通过经纬度计算距离来优化 SQL 查询?
Posted
技术标签:
【中文标题】如何通过经纬度计算距离来优化 SQL 查询?【英文标题】:How to optimize SQL query with calculating distance by longitude and latitude? 【发布时间】:2010-06-22 14:14:09 【问题描述】:我有一张这样结构的表格:
table name: shop
id_shop int(10)
name varchar(200)
latitude double
longitude double
我想计算给定坐标和保存在数据库中的坐标之间的距离。
我当前的查询:
SELECT *
FROM `shop` AS `s`
WHERE
(
( 6371
* ACOS(
SIN( RADIANS( latitude ) )
* SIN( RADIANS( 53.5353010379 ) )
+ COS( RADIANS( latitude ) )
* COS( RADIANS( 53.5353010379 ) )
* COS( RADIANS( 14.7984442616 ) - RADIANS( longitude ) )
)
)
<= 25
)
加上一些JOIN LEFT
的一些数据。
有没有办法优化那个查询? 加入连接大约需要 13 毫秒。
我还需要在此处添加一些 LIMIT
和 COUNT(*)
以获取用于分页的商店总数。
【问题讨论】:
您希望比 13 毫秒快多少? 实际上可能不快于 13 毫秒,但在我的系统中,对于不同的给定坐标 + 分页,会有许多类似的查询。我正在寻找一些最好的方法来处理这个问题。 给定的坐标来自另一个表格,还是来自谷歌地图的点击或移动设备坐标? 我用谷歌地图的地理定位脚本得到它们。 【参考方案1】:这里有一些想法,根据您的具体情况,其中一些可能不适用。
-
您可以将纬度和经度转换为弧度并将其存储在行中。这样可以节省这些计算的成本(实际上是在存储数据时计算一次成本)。
如果您的表非常大,您可以使用简单的线性距离计算而不是 Haversince 公式来限制应用 Haversince 公式的结果。
如果表中还有其他数据可用作良好的第一个过滤器(国家/地区/等),您可以先应用它。
您可以对联接重新排序,以便在距离过滤器之后应用它们,这样您就不会因不符合条件的数据而产生联接成本。
【讨论】:
1.好主意——我应该考虑一下; 2. 是的,桌子很大。线性计算应该如何? 3. 我没有那个数据; 4. 它没有改变任何东西。 2.基本上,你可以只使用毕达哥拉斯定理来计算距离——这可以“足够好”,这取决于你的数据和你在做什么,当你只是在寻找地球上相当有限的区域时,这很好“最近的东西”而不是实际需要准确的距离。您还可以使用 Pythagoras 进行粗略计算以缩小数据集范围,然后对缩小的较小数据集进行更准确、成本更高的 Haversine 计算。【参考方案2】:嗯,首先,您可以在存储纬度和经度时将预先计算的内容存储在数据库中。例如,如果您将纬度和经度预先存储为弧度,则只需在存储每个位置时计算一次 RADIANS(latitude) 和 RADIANS(longitude),而不是每次需要计算距离时(大概不止一次。)
当您第一次填充行时,也可以通过存储 SIN(RADIANS(latitude)) 和 COS(RADIANS(latitude)) 来减少更多...
我猜你随着时间的推移做了很多很多“最接近 X”的计算——这就是人们在面对这种计算时通常会做的事情——而预先计算你能做的通常是第一件事试试看。
【讨论】:
以上是关于如何通过经纬度计算距离来优化 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章