Производительность пространственных запросов SQL Server 2008

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

Маршруты хранятся в виде полилиний (linestrings). В базе также хранятся происшествия, дорожно-транспортные происшествия и тому подобное. Периодически нам нужно запрашивать маршрут, чтобы увидеть, есть ли какие-либо инциденты в радиусе 1k от маршрута.

Соединение по запросу структурировано следующим образом:

    Route r left outer join Incident i on
    r.PolyLine.STDistance(i.Location) < 1000

Теперь я также попробовал что-то вроде этого:

Route r left outer join Incident i on   
r.PolyLine.STBuffer(1000).STIntersects(i.Location) = 1

На данный момент мы пытались улучшить скорость следующим образом:

  1. Уменьшить количество точек вдоль линии
  2. Добавьте пространственный индекс (хотя я не знаю, как его настроить)

1) выше сработало, но недостаточно хорошо, и наводит меня на мысль, что инцидент сравнивался с каждой точкой на маршруте, что кажется действительно неэффективным.

Мы рассматриваем длинные широчайшие как геометрию против географии, поэтому мы получаем доступ к ограничивающей рамке, а также к STContains.

Также рассматривайте возможность вызова сокращения на PolyLine перед проверкой инцидентов.


person CianM    schedule 08.02.2013    source источник
comment
Можете ли вы рассмотреть вопрос о сохранении многоточечного соединения для определенного маршрута, когда вы вставляете маршрут, или это что-то, где вы сохраняете маршрут и запрашиваете только инциденты после этого?   -  person Nicolas Boonaert    schedule 09.02.2013


Ответы (1)


Я бы предложил хранение геометрии. Преимущества изучения географии в этом сценарии, кажется, не перевешивают затраты.

Пространственные индексы очень важны. Один процесс, в котором я использовал пространственные запросы, увеличился с ~ 15 минут до ~ 1 минуты с использованием правильно настроенного пространственного индекса. Однако я не нашел документации о хорошем способе автоматического получения оптимальных настроек для них. Я отвечал на похожий вопрос о настройке пространственного индекса. Предоставленная мной хранимая процедура требует некоторого времени для каждого набора данных, но ее можно запускать в фоновом режиме, пока вы выполняете другую работу.

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

DECLARE @routeBuff geometry
SET @routeBuff = (SELECT r.PolyLine.STBuffer(1000) FROM route r WHERE recordID = 2778) --how ever you select the particular route

SELECT
    *
FROM
    incident i
WHERE
    i.location.STIntersects(@routeBuff) = 1
person Geobility    schedule 08.04.2013