Пространственные индексы не приносят пользы

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

Для некоторого фона:

  • Таблица, содержащая центроиды, имеет 2,5 млн строк.
  • Все пространственные данные в таблице относятся к довольно небольшой области мира, ограничивающая рамка всего этого составляет всего 7643 x 2351 метр.
  • Из этих строк 660 тыс. соответствуют критерию Z.
  • Таблица, содержащая полигоны, имеет 10 тыс. строк.
  • Все пространственные данные в таблице относятся к еще меньшей области мира.
  • Из этих строк 2366 соответствуют критериям имени.
  • Выполнение запроса без каких-либо индексов занимает 11 часов и возвращает 91 тыс. совпадений.

Запрос примерно такой:

select blocks.Id, blocks.WGS84Centroid, polygons.Shape
from 
blocks inner join polygons
    on
    blocks.ZCentre >= (polygons.ZCentre - (polygons.ZLength/2))  and blocks.ZCentre <= (polygons.ZCentre + (polygons.ZLength/2)) and
    polygons.Shape.STIntersects(blocks.WGS84Centroid) = 1
inner join name
    on
    polygons.nameId = name.ID
where name.Name = 'blah'

Итак, чтобы ускорить этот запрос, я добавил пространственный индекс для blocks.WGS84Centroid и один для polygons.Shape.
Анализатор запросов также предложил некластеризованный индекс для блоков.ZCentre, включая блоки.Id и блоки.WGS84Centroid. .

После всего этого вот план запроса:
план запроса SSMS

И стоимость фильтра:
Стоимость фильтра SSMS

Однако после добавления этих трех индексов выполнение запроса по-прежнему занимает столько же времени.
Что мне теперь делать?


person Coxy    schedule 29.05.2012    source источник
comment
@DavidBrabant: индексы были созданы заново; Сомневаюсь, что это помогло бы.   -  person Coxy    schedule 30.05.2012
comment
На самом деле, когда я использую WITH(INDEX(CentroidSpatialIndex)) для подсказки анализатору запросов, я вижу, что поиск по кластеризованному индексу имеет значок /!\ над ним. Я попытался запустить CREATE STATISTICS, но получаю сообщение об ошибке. Столбец «WGS84Centroid» в таблице «dbo.blocks» имеет тип, недопустимый для использования в качестве ключевого столбца в индексе или статистике.   -  person Coxy    schedule 30.05.2012


Ответы (1)


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

В SQL Server 2008 для этого используется значение HIGH на каждом из 4 уровней сетки пространственного индекса. Намекая оптимизатору использовать этот индекс, я сократил соединение до ~1 часа, а не до 10!

В SQL Server 2012 я обнаружил еще несколько интересных аспектов:
Во-первых, функция STIntersects() лучше оптимизирована, если одним из географических объектов является точка, как в моем случае. На моей машине тот же запрос в 2012 году выполнялся в два раза быстрее, чем в 2008 году.

Второй впечатляет гораздо больше! Новый тип пространственного индекса 2012 года использует до 8 уровней тесселяции. Я предполагаю, что плотные данные особенно подходят для этого геометрически более высокого уровня тесселяции в индексе, потому что тот же запрос выполнялся в 45 раз быстрее, когда ему предлагалось использовать новый индекс, а не старый 4-уровневый.

person Coxy    schedule 31.05.2012