2013-03-26 6 views
5

Итак, я только что узнал, что SQL Server 2008 не позволяет индексировать представление с помощью CTE в определении, но он позволяет вам получить alter запрос на добавление with schemabinding в определение представления. Есть ли веская причина для этого? Имеет ли смысл по какой-то причине я не знаю? Я был под впечатлением, что WITH SCHEMABINDING сек главная цель состояла в том, чтобы индексировать видИндексирование просмотров с помощью CTE

новый и улучшенный с более действий запроса

;with x 
as 
(
    select rx.pat_id 
      ,rx.drug_class 
      ,count(*) as counts 
      from rx 
      group by rx.pat_id,rx.drug_class 

) 
select x.pat_id 
     ,x.drug_class 
     ,x.counts 
     ,SUM(c.std_cost) as [Healthcare Costs] 
    from x 
    inner join claims as c 
    on claims.pat_id=x.pat_id 
    group by x.pat_id,x.drug_class,x.counts 

И код, чтобы создать индекс

create unique clustered index [TestIndexName] on [dbo].[MyView] 
(pat_id asc, drug_class asc, counts asc) 
+1

Как в стороне, даже если бы можно было индексировать это представление, агрегированный столбец ('counts') не должен быть частью уникального определения индекса. –

ответ

11
  1. Вы не можете индексировать представление с помощью CTE. Хотя вид может имеет SCHEMABINDING. Подумайте об этом так. Чтобы индексировать представление, он должен удовлетворять двум условиям (и многим другим): (a) что он был создан WITH SCHEMABINDING и (b), что он не содержит CTE. Для того, чтобы схематизировать представление, он не должен удовлетворять условию, что он не содержит CTE.

  2. Я не уверен, что существует сценарий, в котором вид имеет CTE и, будет полезен для индексации. Это касается вашего фактического вопроса, но мой инстинкт заключается в том, что вы пытаетесь проиндексировать это мнение, чтобы волшебным образом сделать его быстрее. Индексированное представление не обязательно будет быстрее, чем запрос к базовым таблицам - есть ограничения по причине, и есть только конкретные варианты использования, где они имеют смысл. Будьте осторожны, чтобы не просто слепо индексировать все ваши взгляды, как волшебную кнопку «идти быстрее». Также помните, что индексированное представление требует обслуживания. Таким образом, это увеличит стоимость любых и всех операций DML в вашей рабочей нагрузке, которые влияют на базовую таблицу (таблицы).

  3. Schemabinding не только для индексирования видов. Также можно использовать на таких вещах, как UDF, чтобы помочь убедить детерминизм, можно использовать в представлениях и функциях для предотвращения изменений в базовой схеме, а в некоторых случаях может повысить производительность (например, когда UDF равен нет связанный с привязкой к схеме, оптимизатору, возможно, придется создавать столбчатую катушку до для обработки любых базовых изменений DDL). Поэтому, пожалуйста, не думайте, что это странно, что вы можете привязать схему к виду, но вы не можете его индексировать. Индексирование представления требует этого, но отношения не взаимны.


Для конкретного сценария, я рекомендую это:

CREATE VIEW dbo.PatClassCounts 
WITH SCHEMABINDING 
AS 
    SELECT pat_id, drug_class, 
     COUNT_BIG(*) AS counts 
    FROM dbo.rx 
    GROUP BY pat_id, drug_class; 
GO 
CREATE UNIQUE CLUSTERED INDEX ON dbo.PatClassCounts(pat_id, drug_class); 
GO 
CREATE VIEW dbo.ClaimSums 
WITH SCHEMABINDING 
AS 
    SELECT pat_id, 
    SUM(c.std_cost) AS [Healthcare Costs], 
    COUNT_BIG(*) AS counts 
    FROM dbo.claims 
    GROUP BY pat_id; 
GO 
CREATE UNIQUE CLUSTERED INDEX ON dbo.ClaimSums(pat_id); 
GO 

Теперь вы можете создать Неиндексированное мнение, что только делает соединение между этими двумя индексированными представлениями, и он будет использовать индексы (вы, возможно, придется использовать NOEXPAND на выпуск более низкого уровня, не уверен):

CREATE VIEW dbo.OriginalViewName 
WITH SCHEMABINDING 
AS 
    SELECT p.pat_id, p.drug_class, p.counts, c.[Healthcare Costs] 
     FROM dbo.PatClassCounts AS p 
     INNER JOIN dbo.ClaimSums AS c 
     ON p.pat_id = c.pat_id; 
GO 

Теперь Тхи все полагают, что стоит предварительно агрегировать эту информацию - если вы выполняете этот запрос нечасто, но данные сильно изменены, лучше не создавать индексированные представления.

Также отметим, что SUM(std_cost) из ClaimSums зрения будет одинаковой для каждой комбинации pat_id + drug_class, так как это только агрегируются pat_id. Я думаю, может быть drug_class в таблице claims, которая также должна быть частью критериев соединения, но я не уверен. Если это так, я думаю, что это может быть свернуто с одним индексированным представлением.

+0

Любое представление, которое тянет данные кросс-сервера, не будет индексироваться, и это имеет прекрасный смысл, потому что вы не можете индексировать то, что не всегда есть. Интересно, имеет ли OP несколько вызовов rpc, ни один код не был отправлен так w/e. – RandomUs1r

+0

@ RandomUs1r Я не думаю, что это сценарий, поскольку OP смог изменить представление и добавить 'SCHEMABINDING'. Если он ссылается на имена из трех или четырех частей, это не должно быть возможным. –

+0

Когда я попытался использовать CTE в представлении, я хотел бы скомбинировать, я получил ошибку «Не могу создать индекс в MyDatabase, потому что он ссылается на CTE. Представления, ссылающиеся на CTE, не могут быть проиндексированы. Уровень 16' ... независимо от уровня 16. Я использую SSM – wootscootinboogie

Смежные вопросы