Задний план
У меня есть таблица, содержащая ПОЛИГОНЫ / МУЛЬТИПОЛИГОНЫ, которые представляют территории клиентов:
- Таблица содержит примерно 8000 строк.
- Примерно 90% многоугольников представляют собой круги.
- Остальные многоугольники представляют один или несколько штатов, провинций или других географических регионов. Необработанные данные многоугольника для этих фигур были импортированы из данные переписи населения США.
- Таблица имеет пространственный индекс и кластерный индекс по первичному ключу. В настройки SQL Server 2008 R2 по умолчанию не было внесено никаких изменений. 16 ячеек на объект, все уровни средние.
Вот упрощенный запрос, который воспроизводит проблему, с которой я столкнулся:
DECLARE @point GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT (-76.992188 39.639538)', 4326)
SELECT terr_offc_id
FROM tbl_office_territories
WHERE terr_territory.STIntersects(@point) = 1
То, что кажется простым и понятным запросом, занимает 12 или 13 секунд для выполнения и имеет очень сложный план выполнения для такого простого запроса.
В моем исследовании несколько источников предлагали добавить к запросу подсказку индекса, чтобы гарантировать, что оптимизатор запросов правильно использует пространственный индекс. Добавление WITH(INDEX(idx_terr_territory))
не имеет никакого эффекта, и из плана выполнения ясно, что он ссылается на мой индекс независимо от подсказки.
Уменьшение полигонов
Казалось возможным, что полигоны территорий, импортированные из данных переписи населения США, излишне сложны, поэтому я создал второй столбец и протестировал уменьшенные полигоны (w / метод Reduce ()) с различной степенью допуска. Выполнение того же запроса, что и выше, к новому столбцу, дало следующие результаты:
- Без уменьшения: 12649 мс
- Уменьшено на 10. 7194 мс
- Уменьшено на 20: 6077 мс
- Уменьшено на 30: 4793 мс
- Уменьшено на 40: 4397 мс
- Уменьшено на 50: 4290 мс
Ясно движется в правильном направлении, но снижение точности кажется неэлегантным решением. Разве не для этого должны быть индексы? И план выполнения для такого базового запроса по-прежнему кажется невероятно сложным.
Пространственный индекс
Из любопытства я удалил пространственный индекс и был ошеломлен результатами:
- Запросы выполнялись быстрее БЕЗ индекса (менее 3 секунд без уменьшения, менее 1 секунды с допуском на уменьшение> = 30)
- План выполнения выглядел намного проще:
Мои вопросы
- Почему мой пространственный индекс замедляет работу?
- Действительно ли необходимо уменьшить сложность многоугольника, чтобы ускорить мой запрос? Снижение точности может вызвать проблемы в будущем, и не похоже, что оно будет хорошо масштабироваться.
Прочие примечания
- Был применен пакет обновления 1 для SQL Server 2008 R2
- Предлагаются дополнительные исследования выполнение запроса внутри хранимой процедуры. Пробовал, и ничего не изменилось.