База данных: Лучшая производительность способ запросить гео-данные местоположения?

По необходимости и TFS являются единственными опциями, о которых я знаю. Я знаю, что они оба использовались на крупномасштабных проектах в Microsoft. Хранилище может масштаб, настолько большой, но я не знаю, идет ли это вне 500-1000 пользователей.

39
задан HankW 30 November 2009 в 03:04
поделиться

7 ответов

Здесь есть хороший документ о производительности геолокации MySQL .

РЕДАКТИРОВАТЬ Я уверен, что здесь используется фиксированный радиус. Кроме того, я не на 100% уверен, что алгоритм вычисления расстояния является наиболее продвинутым (то есть он будет «просверливать» Землю).

Важно то, что этот алгоритм дешев, чтобы дать вам ограничение на количество мячей. строк для правильного поиска расстояния.


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

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

# Pseudo code
# user_lon and user_lat are the source longitude and latitude
# radius is the radius where you want to search
lon_distance = radius / abs(cos(radians(user_lat))*69);
min_lon = user_lon - lon_distance;
max_lon = user_lon + lon_distance;
min_lat = user_lat - (radius / 69);
max_lat = user_lat + (radius / 69);
SELECT dest.*,
  3956 * 2 * ASIN(
    SQRT(
      POWER(
        SIN(
          (user_lat - dest.lat) * pi() / 180 / 2
        ), 2
      ) + COS(
        user_lat * pi() / 180
      ) * COS(
        dest.lat * pi() / 180
      ) * POWER(
        SIN(
          (user_lon - dest.lon) * pi() / 180 / 2
        ), 2
      )
    )
  ) as distance
FROM dest
WHERE 
  dest.lon between min_lon and max_lon AND
  dest.lat between min_lat and max_lat
HAVING distance < radius
ORDER BY distance
LIMIT 10
13
ответ дан 27 November 2019 в 02:53
поделиться

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

Если наборы результатов достаточно малы, вы все равно можете вносить корректировки точности в логику приложения (проще масштабировать по горизонтали, чем базу данных), позволяя выдавать точные результаты.

Взгляните на Брета Слаткина geobox.py , который содержит отличную документацию по этому подходу.

Я все же рекомендую проверить PostgreSQL и PostGIS по сравнению с MySQL, если вы планируете выполнять более сложные запросы в обозримом будущем.

2
ответ дан 27 November 2019 в 02:53
поделиться

У меня была та же проблема, и я написал пост в блоге из 3 частей. Это было быстрее, чем географический индекс.

Введение , Тест , SQL

5
ответ дан 27 November 2019 в 02:53
поделиться

Индексы, которые вы используете, действительно являются индексами B-дерева и поддерживают ключевое слово BETWEEN в вашем запросе. Это означает, что оптимизатор может использовать ваши индексы для поиска домов в вашем «ящике». Однако это не означает, что он всегда будет использовать индексы. Если вы укажете диапазон, содержащий слишком много "совпадений", индексы не будут использоваться.

1
ответ дан 27 November 2019 в 02:53
поделиться

Это выглядит довольно быстро. Меня беспокоит только то, что он будет использовать индекс для получения всех значений в пределах 3 миль от широты, а затем фильтровать их для значений в пределах 3 миль от долготы. Если я понимаю, как работает базовая система, вы можете использовать только один ИНДЕКС для каждой таблицы, поэтому индекс по широте или долготе бесполезен.

Если у вас большой объем данных, он может ускорить вещи, чтобы дать каждому квадрату 1x1 мили уникальный логический идентификатор, а затем сделать дополнительное ограничение на SELECT, которое (area = "23234/34234" OR area = "23235/34234" OR ...) для всех квадратов вокруг вашего point, затем заставьте базу данных использовать этот индекс, а не широту и долготу. Тогда вы будете фильтровать гораздо меньше квадратных миль данных.

0
ответ дан 27 November 2019 в 02:53
поделиться

Дома? У вас их, наверное, не будет даже десяти тысяч. Просто используйте индекс в памяти, например STRTree .

0
ответ дан 27 November 2019 в 02:53
поделиться

Придерживаясь вашего текущего подхода, вы должны сделать одно изменение, Вместо того чтобы индексировать геолокацию и геолонг по отдельности, вы должны иметь составной индекс:

KEY `geolat_geolng` (`geolat`, `geolng`),

В настоящее время ваш запрос будет использовать только один из двух индексов.

1
ответ дан 27 November 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: