Resolución de vistas

El procesador de consultas de SQL Server trata las vistas indizadas y no indizadas de manera diferente.

  • Las filas de una vista indizada se almacenan en la base de datos con el mismo formato que una tabla. Si el optimizador de consultas decide utilizar una vista indizada en un plan de consulta, ésta recibe el mismo tratamiento que la tabla base.

  • Sólo se almacena la definición de una vista no indizada, y no las filas de la vista. El optimizador de consultas incorpora la lógica de la definición de la vista en el plan de ejecución que genera para la instrucción SQL que hace referencia a la vista no indizada.

La lógica utilizada por el optimizador de consultas de SQL Server para decidir cuándo se tiene que usar una vista indizada es muy similar a la lógica que se usa para decidir el índice que se utiliza en una tabla. Si los datos de la vista indizada cubren toda o parte de la instrucción SQL y el optimizador de consultas determina que un índice de la vista es la ruta de acceso menos costosa, el optimizador de consultas elegirá el índice independientemente de si se hace referencia a la vista por su nombre en la consulta. Para obtener más información, consulte Resolver índices de vistas.

Cuando una instrucción SQL hace referencia a una vista no indizada, el analizador y el optimizador de consultas analizan el origen de la instrucción SQL y de la vista, y luego las resuelven en un plan de ejecución único. No hay un plan para la instrucción SQL y otro plan para la vista.

Por ejemplo, considere la vista siguiente:

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

En función de esta vista, ambas instrucciones SQL realizan las mismas operaciones en las tablas base y producen el mismo resultado:

/* 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 > '20020531';

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

La característica del plan de presentación de SQL Server Management Studio muestra que el motor relacional genera el mismo plan de ejecución para estas dos instrucciones SELECT.

Utilizar sugerencias con vistas

Las sugerencias que se colocan en las vistas de una consulta pueden entrar en conflicto con otras sugerencias que se descubren al expandir la vista para obtener acceso a sus tablas base. Cuando esto sucede, la consulta devuelve un error. Por ejemplo, considere la siguiente vista que contiene una sugerencia de tabla en su definición:

USE AdventureWorks;
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;

Ahora supongamos que usted ingresa la siguiente consulta:

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

La consulta genera un error porque la sugerencia SERIALIZABLE que se aplica a la vista Person.AddrState de la consulta se propaga a las tablas Person.Address y Person.StateProvince de la vista cuando ésta se expande. No obstante, la expansión de la vista también mostrará la sugerencia NOLOCK en Person.Address. Debido a que las sugerencias SERIALIZABLE y NOLOCK generan un conflicto, la consulta resultante es incorrecta.

Las sugerencias de las tablas PAGLOCK, NOLOCK, ROWLOCK, TABLOCK o TABLOCKX generan conflictos entre ellas, tal como lo hacen las sugerencias de las tablas HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD y SERIALIZABLE.

Las sugerencias pueden propagarse por los niveles de las vistas anidadas. Por ejemplo, supongamos que una consulta aplica la sugerencia HOLDLOCK a una vista v1. Cuando se expande v1, observamos que la vista v2 forma parte de su definición. La definición de v2 incluye una sugerencia NOLOCK en una de sus tablas base. But this table also inherits the HOLDLOCK hint from the query on view v1. Dado que las sugerencias NOLOCK y HOLDLOCK generan conflictos, la consulta produce un error.

Si se utiliza una sugerencia FORCE ORDER en una consulta que contiene una vista, el orden de combinación de las tablas que se encuentran dentro de la vista se determina mediante la posición de la vista en la construcción ordenada. Por ejemplo, la siguiente consulta realiza una selección entre tres tablas y una vista:

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

Y View1 se define tal como se muestra a continuación:

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

El orden de combinación en el plan de consultas es Table1, Table2, TableA, TableB, Table3.