Полезны ли пространственные данные SQL Server 2008 для сопоставления запросов? - PullRequest
7 голосов
/ 27 августа 2009

У меня есть приложение, в котором у меня есть огромная таблица (100 миллионов записей) информации, каждая строка содержит значение lat / long.

Я постоянно запрашиваю эту таблицу, чтобы получить все записи, которые вписываются в радиус вокруг определенной точки. Например, «все записи в пределах 5 миль от 39,89288, -104,919434»

Для этого у меня есть индекс по столбцам Lat / Long, и я получаю «ограничивающий квадрат» точек, а затем отбрасываю все точки, которые выходят за пределы круга в моем приложении ASP.Net, так как это было быстрее, чем вычисление окружности в SQL Server.
ПРИМЕЧАНИЕ. Это все данные о США, поэтому я считаю, что земля для моих расчетов ровная, что достаточно точно для моих нужд.

Теперь основная проблема с индексом Lat / Long заключается в том, что он является «квадратом» точек, и, поскольку я пытаюсь найти «Lat между x и y» и «Long между x и y», он может не очень эффективно использовать индекс, как если бы я искал «линию» точек.

Я читал о пространственных особенностях SQL 2008, но не нашел достаточно конкретной информации, чтобы понять, полезно ли это для меня.

Таким образом, вопрос заключается в следующем: есть ли в SQL 2008 какой-то другой тип индекса, который сделает этот конкретный тип запроса намного быстрее, чем я могу в SQL 2005?

Ответы [ 4 ]

5 голосов
/ 28 августа 2009

Да! Проверьте эту статью о пространственных индексах. Вы увидите, что эти типы индексов работают лучше, чем подход «индексированный прямоугольник». Кроме того, вы сможете не только эффективно запрашивать «находится рядом с другой точкой», но и выполнять все другие виды географических операций. Вот полный список всех доступных методов для типа.

3 голосов
/ 27 августа 2009

Нашел это:

Для SQL 2008:
http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-2008-proximity-search-with-th

Видимо, это возможно

ПРИМЕЧАНИЕ. Версия этой статьи для SQL 2005 работает не слишком хорошо. Я пробовал подобные вещи, и лучше всего получить квадрат от SQL Server, а затем отбросить круг в своем собственном коде.

Дополнительные ссылки:

http://msdn.microsoft.com/en-us/library/bb964712.aspx
(Наконец-то объяснение !!)

И пример запроса ... По-видимому, это то, как сделать поиск, который я хочу (точки в пределах 5-мильного круга):

DECLARE @Location GEOGRAPHY
SET @Location = GEOGRAPHY::STPointFromText('POINT(73.9517061 40.7934358)',4326).STBuffer(5 * 1600);
SELECT [fields] FROM [table] WHERE LocGeog.STIntersects(@Location) = 1

(LocGeog - столбец География)

Странно, однако, что он работает НАМНОГО медленнее, чем мой обычный старый запрос (в 7 раз медленнее), поэтому я, очевидно, все еще делаю что-то очень неправильное.

1 голос
/ 28 августа 2009

Да, это можно сделать очень хорошо с пространственными данными SQL 2008. Есть некоторый опыт / проб и ошибок (?) В настройке пространственной индексации на правильном уровне сетки, но после этого предполагается, что это будет здорово (передано мне друзьями, я сам не использовал это в производстве).

Для ваших целей (широта / долгота) вам понадобится тип geo graphic и not geo метрика . Я полагаю, что пространственные индексы устанавливают тип индексации «вложенный ограничивающий треугольник», который является улучшением по сравнению с типом предусловия «ограничивающий прямоугольник», который мы вынуждены выполнять в SQL без него.

Хорошо, я бы предложил начать с этого поста в блоге Гранта Фричи "Дом страшного администратора" (скажите ему, что я отправил вам, если вы хотите задать вопросы :-)). Это хорошее объяснение некоторого анализа производительности и настройки пространственных индексов, которые он только начал изучать, а также ссылки на множество других материалов.

0 голосов
/ 17 марта 2011

вы знаете, я делал запросы широты и долготы в Starbucks около 5 лет назад ...

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

Итак, я пришел к этому алгоритму «магического круга».

в основном, у них было несколько запросов, которые выглядели так: выберите * из таблицы1, таблицы2, где UdfDistance (table1.Lat, table1.Long, table2.Lat, table2.Long)> = 250

Я закончил тем, что придумал что-то ДЕЙСТВИТЕЛЬНО похожее, но оно работало НАМНОГО быстрее

выбрать * из таблицы1, таблицы2, где UdfDistance (table1.Lat, table1.Long, table2.Lat, table2.Long)> = 250 и table1.Lat между (table2.Lat - 1) и (table2.Lat + 1) и table1.Long между (table2.Long - 1) и (table2.Long + 1)

По сути, не пытайтесь сравнивать две географические точки, если между ними была разница в 1 градус (широта и долгота).

Другими словами - он использовал НОРМАЛЬНЫЕ ОТНОСИТЕЛЬНЫЕ ИНДЕКСЫ, чтобы отфильтровать большую часть значений, а затем вычисление расстояния UDF было ОЧЕНЬ МНОГО информации для обработки.

Надеюсь, это поможет, я постараюсь помочь уточнить, если мне нужно

...