我对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分钟的开发环境才能完成。
我是否在这里犯了任何经典的错误,还是应该使用更好的查询来检索此数据?
任何帮助将不胜感激。
最佳答案
假设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 ...