Геопоиск (расстояние) в PHP / MySQL (производительность)

У меня есть MySQL-таблица (MyISAM), содержащая около 200 тыс. записей пар широта / долгота, из которых я выбираю, на основе расстояния пар (формула большого круга) от другой пары широта / долгота . (например, все записи, которые находятся в радиусе 10 км около 50,281852, 2,504883)

Моя проблема в том, что этот запрос занимает около 0,28 секунды для выполнения только для этих 200 тыс. записей (которые продолжают увеличиваться с каждым днем). 0,28 секунды было бы нормально, этот запрос выполняется очень часто, так как он поддерживает основную функцию моего веб-приложения, и часто он является частью более крупного запроса.

Есть ли способ ускорить это? MySQL должен каждый раз проходить через все 200 тыс. Записей и выполнять формулу большого круга для каждой записи. Я читал кое-что о геохешировании, R-Trees и тому подобное здесь, в stackoverflow, но я не думаю, что я хочу идти по этому пути. Частично потому, что я никогда не был большим поклонником математики, но в основном потому, что я думаю, что эта проблема уже была решена кем-то более умным, чем я, в библиотеке / расширении / и т. Д. который был тщательно протестирован и регулярно обновляется.

MySQL, кажется, имеет пространственное расширение, но это не обеспечивает функцию расстояния. Должен ли я искать другую базу данных, чтобы поместить эти пары координат? PostgreSQL, похоже, имеет довольно зрелое пространственное расширение. Вы что-нибудь знаете об этом? Или PostgreSQL тоже просто использовал бы формулу большого круга для получения всех записей в определенном регионе?

Может быть, существует специализированный автономный продукт или расширение mysql, которое уже делает то, что я? м ищу?

Или, может быть, есть библиотека PHP, которую я мог бы использовать для вычислений? Используя APC, я мог легко поместить пары широта и долгота в память (эти 200 тыс. Записей занимают около 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

Спасибо!

12
задан Dexter 8 March 2011 в 18:53
поделиться