什么是在半径MySQL(纬度经度)

时间:2016-07-24 03:29:46

标签: mysql sql query-optimization geospatial latitude-longitude

目前我有一些100k +行的表。我正在尝试查找以下数据。

SELECT
*, SQRT(POW(69.1 * (latitude - '49.1044302'), 2) + POW(69.1 * ('-122.801094' - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM stops
HAVING distance < 5
ORDER BY distance limit 100

但是目前这种方法在高负荷下会变慢。有些查询需要20多秒才能完成。

如果有人知道任何更好的优化方法,那就太棒了。

2 个答案:

答案 0 :(得分:2)

首先,如果你有很多地理空间数据,你应该使用mysql的地理空间扩展而不是像这样的计算。然后,您可以create spatial indexes加快许多查询,而且您不必像上面那样编写冗长的查询。

使用与ST_Distance的比较或创建具有感兴趣半径的几何以及ST_within可能会给您带来良好的效果,并且可能比当前快得多。然而,实现这一目标的最好和最快的方法是ST_Dwithin尚未在mysql中实现。

答案 1 :(得分:1)

空间索引肯定取决于MySQL版本。我们的网站也搜索纬度/经度,但我们使用的是旧版本的MySQL(5.1-something)(没有空间索引)。您的查询与我们的查询类似,但我们的查询基于弧度。根据您的确切需求,您可以优化(从您拥有的)优化它。

  1. 绝对从数据库查询中删除sqrt(),它必须为每一行计算 - 仅在显示与用户的实际距离时在最后计算它 - 同时对“距离<5“至”<25“。 Sqrt很昂贵,很容易移动到不需要计算的地方。
  2. 取消引用lat / lon '49 .1044302',因此它严格来说是一个int,并在查询外进行lat / lon类型检查。这不会加快速度,但会阻止因lat / lon变量中的虚假尾随空格而导致错误的转换。
  3. 将5转换为每个方向的实际纬度/批次度差+ / 5以产生限制范围(原样为一个框)。将它添加到查询的“where”部分 - 这个限制将为您提供一个显着减少的,几乎精确的结果行集 - 基本上lat和lon上的x和y +/-范围是结果的上限 - 计算的对角线仅对结果和它们的距离略有细微差别。
  4. 尽可能多地将数学移动到select和where之外 - 它必须扫描整个表并创建一个临时的,在每一行上计算,以给出这些结果。查询中的许多数学运算都可以转换为常量。
  5. 通过将lat / lon(复制)的分辨率降低到另一个字段(并且可能乘以10或100&amp;转换为INT)并添加索引,可以进一步加快行减少(选择框)该字段,并在其中使用+/-边界的字段,至少它将能够使用一个键 - mysql可以减少和那些结果更快。
  6. 至少我们是这样做的。