2016-11-15 4 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 минуты зарядки моей среды разработки.

Я сделал какие-либо классические ошибки здесь, или есть гораздо лучший запрос, который я должен использовать для извлечения этих данных?

Любая помощь должна быть принята с благодарностью.

+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 и где оба актуально для фильтрации и HAVING имеет преимущество в производительности, где фильтрация выполняется на агрегированном колонке, есть некоторые тяжелые расчеты и GROUP BY операции значительно снижают количество строк

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

Может показаться, что сложный предикат неэффективен в предложении where (и именно поэтому была использована группа by /), возможно, вы могли бы уточнить в этом вопросе? –

+0

@Used_By_Already, см. Отредактированный ответ –

+0

@Used_By_Already, переиздан –

Смежные вопросы