Мой пространственный индекс в SQL Server все еще требует много чтений даже по очень простому запросу.Зачем? - PullRequest
4 голосов
/ 04 августа 2011

Мой запрос trival занимает 3 секунды для возврата и требует тонны чтений в соответствии с SQL Profiler. Почему?

У меня есть таблица, заполненная 5 000 000 учетных записей, которые все являются геокодированными точками. Все счета сгруппированы в радиусе 20 миль от города. Мой индекс выглядит так.

CREATE SPATIAL INDEX [IX_CI_Geocode] ON [dbo].[CustomerInformation] 
(
    [Geocode]
)USING  GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = LOW), 
CELLS_PER_OBJECT = 128, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

Когда я запускаю запрос так просто, как показано ниже:

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1

Требуется 3 секунды для возврата, и в соответствии с SQL Server Profiler ему требуется ЦП 12 203 и Чтения 1 218 873. Это похоже на огромные цифры для использования индекса.

Почему это так медленно? Почему это так требует чтения с жесткого диска? Что я могу сделать, чтобы улучшить производительность этого?

Глядя на план запроса, оператор Filter на приведенном ниже снимке экрана составляет 34% от стоимости запроса.

enter image description here

Оператор «Поиск кластеризованного индекса» составляет 63% запроса.

enter image description here

Ответы [ 2 ]

1 голос
/ 05 августа 2011

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

Первый запрос на выборку занимает 5 секунд на 5 миллионах учетных записей.Вторая занимает 3 секунды.

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);
DECLARE @region geography = @g.STBuffer(5000);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.Filter(@region) = 1


select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STIntersects(@region) = 1
0 голосов
/ 15 сентября 2011

Основываясь на моих математических навыках, я чувствую себя как дополнительная работа, если сначала выполняешь STBuffer (), если тебя это не особо интересует.

Не могли бы вы попробовать следующее и сообщить о результатах?

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326);

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode))
where ci.Geocode.STDistance(@g) <= 5000

С другой стороны, есть ли способ предоставить базу данных, чтобы я мог проверить ее для себя?

...