2016-11-15 188 views
1

我對MYSQL查詢並沒有特別瞭解,並且對它們進行了優化,所以我需要一點幫助。我正在檢查一張國際城市的表格,根據表格中的經度和緯度值查找最近的10個城市。優化這個非常慢的MySQL查詢

我使用這個查詢如下:

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 mintues我的開發環境要完成。

我在這裏做過任何經典錯誤,還是有更好的查詢我應該用來檢索這些數據?

任何幫助woould將不勝感激。

+0

您能提供執行計劃嗎? – Jester

+0

在選擇計算一般是緩慢的,所以我認爲這是你的問題 – Jester

+0

請參閱http://stackoverflow.com/a/38771805/267540和http://stackoverflow.com/a/38548557/267540 – e4c5

回答

0

假設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具有性能優勢,其中濾波所聚合的列完成,還有一些重計算和GROUP BY操作顯著減少行數

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

似乎複雜謂詞在where子句中效率低下(這就是爲什麼使用group/by的原因)或許你可以詳細闡述這一點? –

+0

@Used_By_Already,請參閱編輯答案 –

+0

@Used_By_Already,重新編輯 –