Разрешение представлений

Обработчик запросов SQL Server 2005 обращается с индексированными и неиндексированными представлениями по-разному.

  • Строки индексированного представления хранятся в базе данных в том же формате, что и таблица. Если оптимизатор запросов решает использовать индексированное представление в плане запроса, оно обрабатывается так же, как базовая таблица.
  • В случае неиндексированного представления хранится только его определение, но не строки. Оптимизатор запросов интегрирует логику определения представления в план выполнения, создаваемый для инструкции SQL, ссылающейся на неиндексированное представление.

Решение об использовании индексированного представления принимается оптимизатором запросов SQL Server на основе тех же принципов, что и решение об использовании индекса таблицы. Если данные индексированного представления охватывают всю инструкцию SQL или ее часть, а оптимизатор запросов определит, что использовать индекс представления выгодно, он выберет индекс независимо от того, имеется ли в запросе ссылка на представление по его имени. Дополнительные сведения см. в разделе Разрешение индексов для представлений.

Если инструкция SQL ссылается на неиндексированное представление, синтаксический анализатор и оптимизатор запросов анализируют исходный код инструкции SQL и представления, разрешая их в один план выполнения. Отдельных планов для инструкции SQL и представления нет.

Рассмотрим следующее представление:

USE AdventureWorks
GO
CREATE VIEW EmployeeName AS
SELECT h.EmployeeID, c.LastName, c.FirstName
FROM HumanResources.Employee h 
JOIN Person.Contact c
ON h.EmployeeID = c.ContactID;
GO

Обе следующих инструкции SQL, основанных на данном представлении, выполняют одни и те же операции над базовой таблицей, формируя одинаковый результат:

/* SELECT referencing the EmployeeName view. */
SELECT LastName AS EmployeeLastName,
    SalesOrderID, OrderDate
FROM AdventureWorks.Sales.SalesOrderHeader AS soh
JOIN AdventureWorks.dbo.EmployeeName as EmpN
ON (soh.ContactID = EmpN.EmployeeID)
WHERE OrderDate > '31 May, 2002';

/* SELECT referencing the Contact and Employee tables directly. */
SELECT LastName AS EmployeeLastName,
    SalesOrderID, OrderDate
FROM AdventureWorks.Sales.SalesOrderHeader AS soh
 JOIN AdventureWorks.Person.Contact as c
 ON soh.ContactID = c.ContactID
JOIN AdventureWorks.HumanResources.Employee as e
ON e.EmployeeID =c.ContactID
WHERE OrderDate > '31 May, 2002';

Используя входящее в среду SQL Server Management Studio средство отображения планов, нужно убедиться, что для обеих этих инструкций SELECT ядро СУБД создает один и тот же план выполнения.

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

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

USE AdventureWorks
CREATE VIEW Person.AddrState WITH SCHEMABINDING AS
SELECT a.AddressID, a.AddressLine1, 
    s.StateProvinceCode, s.CountryRegionCode
FROM Person.Address a WITH (NOLOCK), Person.StateProvince s
WHERE a.StateProvinceID = s.StateProvinceID

Предположим, что вводится следующий запрос:

SELECT AddressID, AddressLine1, StateProvinceCode, CountryRegionCode
FROM Person.AddrState WITH (SERIALIZABLE)
WHERE StateProvinceCode = 'WA'

Он завершится ошибкой потому, что подсказка SERIALIZABLE, примененная в запросе к представлению Person.AddrState, при расширении представления распространится и на таблицу Person.Address, и на таблицу Person.StateProvince. Однако при расширении представления будет также обнаружена подсказка NOLOCK, ассоциированная с таблицей Person.Address. Из-за конфликта подсказок SERIALIZABLE и NOLOCK итоговый запрос окажется неправильным.

Между собой конфликтуют табличные подсказки PAGLOCK, NOLOCK, ROWLOCK, TABLOCK и TABLOCKX, а также подсказки таблиц HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD и SERIALIZABLE.

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

Если в запросе, включающем представление, используется подсказка FORCE ORDER, порядок соединения таблиц в представлении определяется по позиции представления в конструкции упорядочения. Например, приведенный ниже запрос выбирает данные из трех таблиц и представления:

SELECT * FROM Table1, Table2, View1, Table3
WHERE Table1.Col1 = Table2.Col1 
AND Table2.Col1 = View1.Col1
AND View1.Col2 = Table3.Col2
OPTION (FORCE ORDER)

Допустим, что представление View1 определено следующим образом:

CREATE VIEW View1 AS
SELECT Colx, Coly FROM TableA, TableB
WHERE TableA.ColZ = TableB.Colz

В этом случае порядок соединения таблиц в плане запроса будет таким: Table1, Table2, TableA, TableB, Table3.

См. также

Основные понятия

Разрешение индексов для представлений
Проектирование и реализация представлений

Справка и поддержка

Получение помощи по SQL Server 2005