2016-03-21 2 views
2

У меня есть запрос, который возвращает все записи, упорядоченные по расстоянию от фиксированной точки, по сравнению с полем в моей базе данных MySQL 5.7.Улучшение производительности пространственного запроса MySQL

Для простого примера, предположим, что это выглядит следующим образом:

SELECT shops.*, st_distance(location, POINT(:lat, :lng)) as distanceRaw 
FROM shops 
ORDER BY distanceRaw 
LIMIT 50 

Мой фактический запрос также должен сделать несколько объединений, чтобы получить дополнительные данные для результатов.

Проблема заключается в том, что для сортировки данных по расстоянию ему необходимо рассчитать расстояние по каждой отдельной записи в базе данных (в настоящее время около 100 000 записей).

Я не могу кэшировать запрос, поскольку он будет специфичен только для этих исходных координат.

Есть ли способ ограничить данные, которые необходимо рассчитать? Например, надежный приблизительный расчет для ближайших магазинов, скажем, +/- 3 градуса для lat + lng? Так что ему нужно обработать только подмножество данных?

Если у кого-то есть опыт в такой оптимизации, я бы очень хотел получить совет, спасибо.

+0

Я подробно расскажу об этой проблеме и о хорошем решении в [моем блоге] (http://mysql.rjweb.org/doc.php/latlng). –

ответ

1

Да, вы можете использовать какое-то простое приближение, где критерии отфильтровывают те места, которые являются obvioulsy из радиуса. This great blog post под названием «Быстрый ближайшего Искатель положения для SQL (MySQL, PostgreSQL, SQL Server)» описывает такие оптимизации:

Помните, что от нашей справочной информации ранее в этой статье, что степень широты 111.045 км. Итак, если у нас есть индекс на наш столбец широты, мы можем использовать предложение SQL, подобное этому, чтобы устранить точки, которые слишком далеко на север или слишком далеко на юг, чтобы возможно быть в радиусе 50 км.

latitude BETWEEN latpoint - (50.0/111.045) AND latpoint + (50.0/111.045)

Это ИНЕКЕ позволяет MySQL использовать индекс, чтобы опустить много широты точки перед вычислением гаверсинуса расстояния формулы. Он позволяет MySQL выполнять сканирование диапазона по индексу широты.

Наконец, мы можем использовать аналогичное, но более сложное предложение SQL, чтобы устранить точек, которые находятся слишком далеко от востока или запада. Этот пункт более сложный , потому что градусы долготы меньше расстояний, дальше от от экватора мы двигаемся. Это формула.

longitude BETWEEN longpoint - (50.0/(111.045 * COS(RADIANS(latpoint)))) AND longpoint + (50.0/(111.045 * COS(RADIANS(latpoint))))

Таким образом, положить все это вместе, этот запрос находит neareast 15 очков , которые находятся в пределах ограничивающего прямоугольника 50 км от (latpoint, longpoint).

Приведенное выше описывает теоретический фон для ограничивающих прямоугольников.

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