Обновление. После написания этой статьи мы решили перенести наши геопространственные данные в базу данных 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
. (Не используется в примере запроса.)
SELECT TOP (1) * FROM myTable ga WITH(INDEX([SpatialIndex_sptGeoPolygonBounds])) WHERE ga.sptGeoPolygonBounds.STIntersects(@point) = 1
- person Dawood Awan   schedule 29.04.2019