Как приложение выполняет поиск по близости? Например, пользователь вводит почтовый код, затем приложение перечисляет все предприятия в пределах 20 миль, заказанных по близости.
Я хочу построить что-то подобное в PHP и MySQL. Правильно ли этот подход?
Это нормально? На шаге 3 я собираюсь рассчитать близость для каждого запроса. Лучше ли иметь таблицу PROXIMITY, в которой указано расстояние между каждым бизнесом и несколькими ссылочными позициями?
Если есть достаточное количество записей для скорости, это способ их индексации раньше времени.
Определите сетку бункеров около 20 миль на боку. Сохраните номер ячейки с записью каждого магазина. Во время поиска вычислите числа всех бинов, которые пересекают 20-мильный радиус от точки поиска. Затем загрузите все магазины в любом из этих ящиков и действуйте по-прежнему.
Мы используем это, чтобы сделать много тысяч очков. Важно, если вы выполняете это в SQL, чтобы иметь индекс в столбце Широта и долгота. Мы попытались сделать это в SQL 2008 с пространственными индексами, но мы действительно не видели увеличения производительности, которого мы ожидали. Хотя, если вы хотите рассчитать на определенном расстоянии от ZIP, вам нужно подумать о том, собираетесь ли вы использовать ZIP-центр или многоугольное представление почтового индекса.
Haversine forumla – хорошее место для начала.
У нас не было проблем с производительностью, вычисляющих расстояние «на лету», мы заранее рассчитываем его для некоторых приложений, где мы знаем моменты раньше времени, и будут миллионы записей.
SELECT [DistanceRadius]= 69.09 * DEGREES( ACOS( SIN( RADIANS(latitude) )*SIN( RADIANS(@ziplat) ) + COS( RADIANS(latitude) )*COS( RADIANS(@ziplat) ) * COS( RADIANS(longitude - (@ziplon)) ) ) ) ,* FROM table ) sub WHERE sub.DistanceRadius < @radius
Мы делаем это примерно в 1200 местах. Я бы просто использовал формулу Хаверсина «на лету», хотя в зависимости от вашего приложения лучше было бы хранить его в PHP вместо SQL. (Наша реализация в .net, поэтому ваше перемещение может меняться).
На самом деле наш самый большой недостаток в том, как мы его реализовали, заключается в том, что каждый расчет (до недавнего времени) должен был быть рассчитан на уровне данных, который был болезненно медленным (когда я говорю «медленно», я действительно имею в виду немедленное, это заняло секунду или около того ), но это было связано с тем, что он должен был рассчитать расстояние для всех 1200 мест на основе поставленного почтового индекса.
В зависимости от выбранного вами маршрута существуют способы ускорения вычислений расстояния расстояния, просмотра долготы и широты и удаления тех, которые находятся за пределами заданного диапазона (например, если вы просматриваете весь адрес в пределах 20 миль, долготу, вы можете рассчитать, что все адреса должны находиться в 20 милях.) Это может ускорить ваш запрос, если это необходимо.
Мы действительно посмотрели на сохранение всех возможных комбинаций в нашей базе данных. На самом деле это звучит так, будто это может быть большой магазин данных, но это действительно не в большом объеме вещей. С индексами это может быть довольно быстро, и вам не нужно беспокоиться об оптимизации алгоритмов и т. Д. Мы решили против этого, потому что у нас было уравнение в C #, и это позволило нам кэшировать информацию, необходимую для выполнения всех вычислений в бизнес-уровня. Либо все будет работать отлично, это всего лишь вопрос ваших предпочтений.