【问题标题】:Optimising this very slow MySQL Query优化这个非常慢的 MySQL 查询
【发布时间】:2016-11-15 09:50:51
【问题描述】:

我对 MYSQL 查询和优化它们不是特别了解,所以我需要一些帮助。我正在检查一张国际城市表,根据表中的经度和纬度值查找最近的 10 个城市。

我使用的查询如下:

SELECT City as city,
       SQRT(POW(69.1 * (Latitude - 51.5073509), 2) +
           POW(69.1 * (-0.1277583 - Longitude) * COS(Latitude / 57.3), 2)) AS distance
from `cities`
group by `City`
having distance < 50
order by `distance` asc
limit 10

(经度和纬度值显然是在我的代码中动态放置的)

有时这可能需要我的开发环境大约 3-4 分钟才能完成。

我是否在这里犯了任何典型的错误,或者我应该使用更好的查询来检索这些数据?

非常感谢任何帮助。

【问题讨论】:

  • 能否提供一个执行计划?
  • 选择中的计算通常很慢,所以我认为这是你的问题
  • 您可以添加过滤器以首先限制矩形 WHERE abs(Latitude-51.5073509)
  • 查询为假。将距离放在 HAVING 子句中是没有意义的。你到底想达到什么目的?

标签: mysql sql


【解决方案1】:

假设 City 是唯一的,并且您正在滥用 GROUP BY 和 HAVING 以获得更清晰的代码

SELECT City as city,
       SQRT(POW(69.1 * (Latitude - 51.5073509), 2) +
           POW(69.1 * (-0.1277583 - Longitude) * COS(Latitude / 57.3), 2)) AS distance

from `cities`

where  SQRT(POW(69.1 * (Latitude - 51.5073509), 2) +
           POW(69.1 * (-0.1277583 - Longitude) * COS(Latitude / 57.3), 2))  < 50

order by `distance` asc

limit 10

  • 如果 City 是唯一的,则聚合在单行上完成。
    MySQL 使用排序操作来实现 GROUP BY。
    排序复杂度为 O(n*log(n)),因此如果没有索引,这将导致 GROUP BY 的复杂度。
  • 如果 City 不是唯一的,则 HAVING CLAUSE 中的过滤是在任意一行上完成的,这肯定不是 OP 的意图。

HAVING 和 WHERE 都与过滤相关并且 HAVING 具有性能优势的情况是,过滤是在聚合列上完成的,存在一些繁重的计算,并且 GROUP BY 操作显着减少了行数

select x,... from ... group by x having ... some heavy calculations on x ...

【讨论】:

  • 似乎复杂谓词在 where 子句中效率低下(这就是为什么使用 group by/have)也许您可以详细说明这一点?
猜你喜欢
  • 1970-01-01
  • 2014-07-04
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2012-02-08
  • 1970-01-01
相关资源
最近更新 更多