Нужна помощь в оптимизации потенциально ошибочного пространственного SQL-запроса

Обновление. После написания этой статьи мы решили перенести наши геопространственные данные в базу данных ElasticSearch, что дало лучшие результаты.

Я новичок в SQL, и мне нужна помощь в оптимизации пространственного запроса, чтобы он выполнялся менее чем за 2 секунды. Мы уже попробовали некоторые предложения, найденные на разных сайтах (подробнее об этом ниже).

Фон

У нас есть таблица [Id, Geometry], содержащая около 300 000 геометрических фигур различного размера и сложности, хранящихся как типы данных геометрии. Мы создали пространственный индекс для геометрии, используя фрагмент кода ниже.

CREATE SPATIAL INDEX [IX_Geometry_Spatial]
ON [dbo].[Geometries] ([Geometry]) USING  GEOMETRY_AUTO_GRID 
WITH  (
        BOUNDING_BOX = (XMAX = 24.43359375, XMIN = 10.810546875, YMAX = 69.2249968541159, YMIN = 55.2791152920156)
      );

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

DECLARE @g geometry;  
SET @g = geometry::STGeomFromText('POLYGON ((x0 y0, ...))', 4326); -- A Worst Case Polygon containing 1442 data points

SELECT Count(Id)
FROM Geometries
WHERE Geometries.Geometry.Filter(@g.Reduce(.25)) = 1

Для некоторых наихудших исходных геометрических фигур (больших, сложных многоугольников) это выполнение занимает около 7-10 секунд.

Это план выполнения запроса:  введите описание изображения здесь

Мы видим, что мы попали в пространственный индекс, но самая дорогая операция - это clustered index seek (Clustered)

Подробная информация о поиске в кластеризованном индексе:

введите описание изображения здесь

Подробности поиска по пространственному индексу:

введите описание изображения здесь

Вопросов

Разве тяжелая работа не должна выполняться пространственным индексом, а не кластеризованным индексом?

Можно ли улучшить запрос, изменив настройки пространственного индекса? Какие настройки мы должны использовать (для GRIDS, CELLS_PER_OBJECT и т. Д.)?

Как можно в целом сократить время выполнения или на 7-10 секунд, что можно ожидать от такого типа запроса?

То, что мы пробовали, помогло

Каждый из них сэкономил примерно несколько секунд.

  • Проверено на фрагментацию индексов и перестроены индексы.
  • Метод пересечения изменен с STIntersect() на Filter()
  • Уменьшил входную геометрию с помощью Reduce(.25). Это уменьшает геометрию с 1442 точек данных до 7. (Если мы решим использовать это, она должна быть динамической для разных входных данных, но это уже другая проблема.)
  • Введен новый столбец таблицы SimpleGeometry, который содержит ограничивающие рамки всех геометрических объектов из столбца Geometry. Создал новый SimpleGeometry пространственный индекс и использовал SimpleGeometry для поиска вместо Geometry. (Не используется в примере запроса.)

person hittaKAFFE    schedule 28.11.2018    source источник
comment
Я рекомендую сделать больше предварительной обработки. Вы начали нормально с ограничивающими рамками. Я бы улучшил это, сделав трехмерную сетку, и каждый куб сетки будет содержать список своих объектов, которые ему мешают. Цель должна заключаться в том, чтобы как можно быстрее улучшить местоположение ближайших объектов, а затем перейти к детальному вычислению с как можно меньшим количеством объектов.   -  person Honza P.    schedule 02.01.2019
comment
Я считаю, что самой большой проблемой может быть функция с табличным значением. Эти штуки такие же медленные, как езда на черепахе задом наперёд.   -  person Luis Cazares    schedule 26.03.2019
comment
У меня был аналогичный запрос, в котором пространственный индекс не использовался для поиска. Попробуйте заставить SQLServer использовать индекс с помощью WITH (INDEX ([Index_Name])). SELECT TOP (1) * FROM myTable ga WITH(INDEX([SpatialIndex_sptGeoPolygonBounds])) WHERE ga.sptGeoPolygonBounds.STIntersects(@point) = 1   -  person Dawood Awan    schedule 29.04.2019


Ответы (1)


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

person Roger    schedule 18.05.2019
comment
Будьте осторожны, чтобы не быть ошибочно принятым за вопрос, где должен быть ответ. Перефразирование без реторического вопроса может помочь. - person Yunnosch; 18.05.2019