У меня есть MySQL-таблица (MyISAM), содержащая около 200 тыс. записей пар lat/long, которые я выбираю, исходя из расстояния пар (формула большого круга) от другой пары lat/long. (например, все записи, которые находятся в радиусе 10 км около 50,281852, 2,504883).
Моя проблема в том, что этот запрос занимает около 0,28 сек. для запуска только для этих 200 тыс. записей (которые продолжают получать больше каждый день). Пока 0,28 сек. было бы нормально нормально, этот запрос выполняется очень часто, поскольку он обеспечивает основную функцию моего веб-приложения и часто делает его частью более крупного запроса.
Есть ли способ ускорить это? Obviosly MySQL должен каждый раз запускать все записи 200k и выполнять формулу большого круга для каждой записи. Я читал кое-что о geohashing, R-Trees и т.д. Здесь, в stackoverflow, но я не думаю, что так хочу. Отчасти потому, что я никогда не был большим поклонником математики, но в основном потому, что я думаю, что эта проблема уже была решена кем-то умнее меня в библиотеке/расширении/и т.д. который был протестирован широко и регулярно обновляется.
MySQL, похоже, имеет пространственное расширение, но не обеспечивает функцию расстояния. Должен ли я искать другую базу данных для ввода этих пар координат? PostgreSQL, похоже, имеет довольно зрелое пространственное расширение. Вы знаете что-нибудь об этом? Или PostgreSQL просто просто использовал формулу большого круга, чтобы получить все записи в определенном регионе?
Есть ли специализированный автономный продукт или mysql-расширение, которое уже делает то, что я ищу?
Или может быть библиотека PHP, которую я мог бы использовать для выполнения вычислений? Используя APC, я мог легко вставить парные длины в память (эти 200k записей занимают около 5 МБ), а затем запустить запрос внутри PHP. Проблема с этим подходом однако заключается в том, что тогда у меня будет запрос MySQL, такой как SELECT.. FROM.. WHERE id in (id1, id2,..) для всех результатов, которые могут быть до нескольких тысяч. Насколько хорошо MySQL обрабатывает запросы, подобные этим? И тогда (поскольку это задача с хрустом числа), будет ли это делать в PHP достаточно быстро?
Любые другие идеи, которые я должен/не должен делать?
Для полноты, вот пример запроса, лишенный каких-либо нерелевантных частей (как я уже сказал, обычно это часть большего запроса, в который я присоединяюсь к нескольким таблицам):
SELECT id, 6371 * acos( sin( radians( 52.4042924 ) ) * sin( radians( lat ) ) + cos( radians( 50.281852 ) ) * cos( radians( lat ) ) * cos( radians( 2.504883 ) - radians( lon ) ) ) AS dst
FROM geoloc
HAVING dst <10
ORDER BY dst ASC
Спасибо!