Compartilhar via


Resolução de exibição

O processador de consultas do SQL Server trata as exibições indexadas e não indexadas de forma diferente:

  • As linhas de uma exibição indexada são armazenadas no banco de dados no mesmo formato de uma tabela. Se o otimizador de consulta decidir usar uma exibição indexada em um plano de consulta, a exibição indexada será tratada da mesma forma que uma tabela base.

  • Somente a definição de uma exibição não indexada é armazenada, e não as linhas da exibição. O otimizador de consulta incorpora a lógica da definição de exibição no plano de execução criado para a instrução SQL que referencia a exibição não indexada.

A lógica usada pelo otimizador de consulta do SQL Server para decidir quando usar uma exibição indexada é semelhante à lógica usada para decidir quando usar um índice em uma tabela. Se os dados na exibição indexada abrangerem toda ou parte da instrução SQL, e o otimizador de consulta determinar que um índice na exibição é o caminho de acesso de baixo custo, o otimizador de consulta escolherá o índice independentemente de a exibição ser referenciada pelo nome na consulta. Para obter mais informações, consulte Resolvendo índices em exibições.

Quando uma instrução SQL referencia uma exibição não indexada, o analisador e o otimizador de consulta analisam a origem da instrução SQL e a exibição. Depois, as resolvem em um único plano de execução. Não há um plano para a instrução SQL e um plano separado para a exibição.

Por exemplo, considere a seguinte exibição:

USE AdventureWorks2008R2;
GO
CREATE VIEW EmployeeName AS
SELECT h.BusinessEntityID, p.LastName, p.FirstName
FROM HumanResources.Employee AS h 
JOIN Person.Person AS p
ON h.BusinessEntityID = p.BusinessEntityID;
GO

Com base nessa exibição, estas duas instruções SQL executam as mesmas operações nas tabelas base e produzem os mesmos resultados:

/* SELECT referencing the EmployeeName view. */
SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate
FROM AdventureWorks2008R2.Sales.SalesOrderHeader AS soh
JOIN AdventureWorks2008R2.dbo.EmployeeName AS EmpN
ON (soh.SalesPersonID = EmpN.BusinessEntityID)
WHERE OrderDate > '20020531';

/* SELECT referencing the Person and Employee tables directly. */
SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate
FROM AdventureWorks2008R2.HumanResources.Employee AS e 
JOIN AdventureWorks2008R2.Sales.SalesOrderHeader AS soh
ON soh.SalesPersonID = e.BusinessEntityID
JOIN AdventureWorks2008R2.Person.Person AS p
ON e.BusinessEntityID =p.BusinessEntityID
WHERE OrderDate > '20020531';

O recurso Plano de Execução do SQL Server Management Studio mostra que o mecanismo relacional cria o mesmo plano de execução para as duas instruções SELECT.

Usando dicas com exibições

As dicas colocadas em exibições em uma consulta podem entrar em conflito com outras dicas descobertas quando a exibição é expandida para acessar suas tabelas base. Quando isso acontece, a consulta retorna um erro. Por exemplo, considere a seguinte exibição que contém uma dica de tabela em sua definição:

USE AdventureWorks2008R2;
GO
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;

Agora suponha que você insira esta consulta:

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

Há uma falha na consulta, porque a dica SERIALIZABLE aplicada na exibição Person.AddrState na consulta é propagada nas tabelas Person.Address e Person.StateProvince na exibição ao ser expandida. No entanto, a expansão da exibição também revela a dica NOLOCK em Person.Address. Como há conflito das dicas SERIALIZABLE e NOLOCK, a consulta resultante está incorreta.

As dicas de tabela PAGLOCK, NOLOCK, ROWLOCK, TABLOCK ou TABLOCKX são conflitantes entre si, assim como as dicas de tabela HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE.

As dicas podem ser propagadas pelos níveis de exibições aninhadas. Por exemplo, suponha que uma consulta se aplique à dica HOLDLOCK em uma exibição v1. Quando v1 é expandida, observamos que a exibição v2 faz parte da sua definição. A definição de v2 contém uma dica NOLOCK em uma de suas tabelas base. Mas essa tabela também herda a dica HOLDLOCK da consulta na exibição v1. Como há conflito nas dicas NOLOCK e HOLDLOCK, há falha na consulta.

Quando a dica FORCE ORDER é usada em uma consulta que contém uma exibição, a ordem de junção das tabelas na exibição é determinada pela posição da exibição na construção ordenada. Por exemplo, a seguinte consulta faz a seleção a partir de três tabelas e uma exibição:

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

E View1 é definido como mostrado abaixo:

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

A ordem de junção no plano de consulta é Table1, Table2, TableA, TableB, Table3.