Оптимизация поиска на карте - PullRequest
0 голосов
/ 08 сентября 2011

для одного из наших клиентов мы предоставляем систему для извлечения ближайших N ориентиров из почтового индекса пользователя. У нас есть база данных всех доступных почтовых индексов (650 000+) с соответствующими координатами (широта и долгота), а также все 400+ ориентиров в стране.

На данный момент мы используем следующий процесс поиска ближайших N ориентиров

  1. Получить широту и длину выбранного почтового индекса
  2. Получить координаты всех ориентиров
  3. Заказать их по формуле географического расстояния
  4. Возьмите ближайшие N + 2 ориентира и получите реальное расстояние до них, используя следующий процесс
    • проверить, хранится ли расстояние между координатами в таблице кэша расстояний
    • если нет, то идет к движку карты, извлекает расстояние и сохраняет его в кеше
  5. Изменить порядок списка и вернуть первые N ближайших ориентиров

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

Мы пытались кэшировать для всех почтовых индексов расстояние до ближайших ориентиров М, но таблица получит дополнительные 6 ГБ данных, и заполнение займет около 250 дней, поскольку запрос занимает примерно 30 секунд.

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

Какие оптимизирующие решения вы видите в этой ситуации. Спасибо.

Ответы [ 2 ]

1 голос
/ 08 сентября 2011

Это должно быть сделано на уровне базы данных.Вам следует использовать базу данных с географическим расширением в качестве SQL Server 2008 R2 или отличный вариант с открытым исходным кодом PostGre SQL с расширением PostGIS.С их помощью вы сохраняете географические BLOB вместо координат, и есть много встроенных функций для расчета географии, которые позаботятся о выполнении шагов 2-5.

Я предлагаю вам начать здесь: http://postgis.refractions.net/

Привет

1 голос
/ 08 сентября 2011

Вы можете попробовать повторный подход.

  1. Выберите значение для использования в качестве «радиуса»
  2. Просмотрите все результаты и выберите только один + - радиус по горизонтали и вертикали (согласно геолокации
  3. если возвращено недостаточно строк, увеличьте «радиус» и начните снова
  4. Теперь выполните расчет расстояния и используйте PriorityQueue, чтобы минимизировать количество вычислений, используемых в этом виде, и выберите необходимые элементы
...