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

Я создал индексированное представление (чтобы сэкономить время на очень трудоемкой агрегации), используя следующий код (упрощенный):

CREATE VIEW vCosts WITH SCHEMABINDING AS
SELECT   ProjectID
         ,YEAR(Date) AS Year
         ,SUM(Cost) AS YearlyCost
FROM     dbo.DailyAssignments
GROUP BY ProjectID
         ,YEAR(Date)

CREATE UNIQUE CLUSTERED INDEX IX_vCosts ON vCosts (Year, ProjectID)

Выполнение SELECT * в этом представлении занимает секунду. Но следующий запрос занимает 30 секунд (и экспоненциально хуже, если включено больше лет):

SELECT *
FROM   vCosts
WHERE  Year = 2001

План выполнения указывает, что он фактически использует базовую таблицу, а не представление (точнее, кажется, что он использует кластеризованный первичный ключ таблицы DailyAssignments, а не индекс представления). SELECT * в представлении использует индекс, как и ожидалось.

И у меня нет такой же проблемы с другим полем. Следующее также использует индекс представления и завершается менее чем за секунду:

SELECT *
FROM   vCosts
WHERE  ProjectID = 1

Может ли кто-нибудь помочь мне понять, что происходит?


person Serital    schedule 28.05.2014    source источник


Ответы (1)


Попробуйте добавить WITH (NOEXPAND) после просмотра. У меня тоже была эта пробема.

SELECT *
FROM   vCosts WITH (NOEXPAND)
WHERE  ProjectID = 1

Когда для представления указано NOEXPAND, оптимизатор запросов рассматривает возможность использования любых индексов, определенных для представления. Параметр NOEXPAND, указанный в необязательном предложении INDEX(), заставляет оптимизатор запросов использовать указанные индексы. NOEXPAND можно указать только для индексированного представления и нельзя указать для неиндексированного представления.

Источник здесь http://technet.microsoft.com/en-us/library/ms181151(v=sql.105).aspx

person Darka    schedule 28.05.2014
comment
Это сработало, спасибо! Но зачем это нужно? Можете ли вы направить меня к источнику, который я могу прочитать, чтобы понять, почему оптимизатор решил расширить представление в моем случае (используя ГОД (дата))? - person Serital; 28.05.2014