Compartir a través de


Diseñar vistas indizadas

Las vistas también se denominan tablas virtuales porque el conjunto de resultados que devuelve la vista tiene el mismo formato general que una tabla con columnas y filas, y se puede hacer referencia a las vistas de la misma forma que a las tablas de las instrucciones SQL. El conjunto de resultados de una vista estándar no se almacena permanentemente en la base de datos. Cada vez que una consulta hace referencia a una vista estándar, SQL Server sustituye internamente la definición de la vista dentro de la consulta hasta que se forme una consulta modificada que solamente haga referencia a las tablas base. Posteriormente ejecuta la consulta resultante de la forma habitual. Para obtener más información, vea Resolución de vistas.

Para una vista estándar, la sobrecarga resultante de generar de forma dinámica el conjunto de resultados para cada consulta que hace referencia a una vista puede ser importante para las vistas que implican el procesamiento complejo de un gran número de filas, como la agregación de grandes cantidades de datos o la combinación de muchas filas. Si en las consultas se hace referencia con frecuencia a estas vistas, puede mejorar el rendimiento mediante la creación de un índice agrupado único en la vista. Cuando en una vista se crea un índice agrupado único, el conjunto de resultados se almacena en la base de datos como si se tratara de una tabla con un índice agrupado.

Otra ventaja de la creación de un índice en una vista es que el optimizador se inicia utilizando el índice de la vista en las consultas que no nombran directamente la vista en la cláusula FROM. Las consultas existentes pueden beneficiarse de la eficiencia mejorada de la recuperación de datos desde la vista indizada sin tener que volver a codificarse. Para obtener más información, vea Resolver índices de vistas.

Según se realizan las modificaciones en los datos de las tablas base, éstas se reflejan en los datos almacenados en la vista indizada. El requisito de que el índice agrupado de la vista sea único mejora la eficacia con la que SQL Server puede encontrar en el índice las filas cuyos datos se hayan modificado.

La capacidad del optimizador de consultas para sacar partido de las vistas indizadas al procesar consultas ha mejorado respecto a versiones anteriores en los casos en que la definición tanto de la vista como de la consulta contienen los siguientes elementos coincidentes:

  • Expresiones escalares. Por ejemplo, el optimizador de consultas puede hacer coincidir la siguiente consulta con una expresión escalar en su predicado:

    SELECT ColA, ColB FROM TableT WHERE ColC * (ColD + 10) > 50
    

    Para un índice creado en esta vista:

    CREATE VIEW V1 WITH SCHEMABINDING AS
    SELECT ColA, ColB, ColC * (ColD + 10) AS ExpCol
    FROM dbo.TableT 
    

    Las expresiones escalares que incluyen funciones definidas por el usuario también pueden coincidir de una manera parecida.

  • Funciones de agregado escalares. Por ejemplo, la siguiente consulta que contiene una función de agregado escalar en su lista SELECT:

    SELECT COUNT_BIG (*) FROM dbo.TableT
    

    Puede coincidir con un índice creado en esta vista:

    CREATE VIEW V2 WITH SCHEMABINDING AS
    SELECT COUNT_BIG (*) AS Cnt 
    FROM dbo.TableT 
    

El optimizador de consultas también considerará lo siguiente al seleccionar un plan de consulta:

  • Si un intervalo de valores definido en un predicado de consulta está comprendido dentro de un intervalo definido en una vista indizada. Por ejemplo, suponga que se crea un índice en la siguiente vista:

    CREATE VIEW V1 WITH SCHEMABINDING AS
    SELECT ColA, ColB, ColC FROM dbo.TableT
    WHERE ColA > 1 and ColA < 10
    

    Ahora suponga la siguiente consulta:

    SELECT ColB, ColC FROM dbo.TableT
    WHERE ColA > 3 and ColA < 7
    

    El optimizador de consultas haría coincidir esta consulta con la vista V1 porque el intervalo entre 3 y 7 definido en la consulta está comprendido dentro del intervalo entre 1 y 10 definido en la vista indizada.

  • La medida en que una expresión definida en una consulta es equivalente a la definida en una vista indizada. SQL Server intenta hacer coincidir expresiones según sus referencias de columna, literales, los operadores lógicos AND, OR, NOT, BETWEEN e IN, y los operadores de comparación =, <>, >, <, >= y <=. No se tienen en cuenta los operadores aritméticos, como + y %, ni los parámetros.

    Por ejemplo, el optimizador de consultas haría coincidir la siguiente consulta:

    SELECT ColA, ColB from dbo.TableT
    WHERE ColA < ColB 
    

    Con un índice creado en esta vista:

    CREATE VIEW V1 WITH SCHEMABINDING AS
    SELECT ColA, ColB FROM dbo.TableT
    WHERE ColB > ColA 
    

Recuerde que, como en todos los índices, SQL Server sólo elige utilizar una vista indizada en su plan de consulta si el optimizador de consultas determina que es útil hacerlo.

Las vistas indizadas se pueden crear en cualquier edición de SQL Server 2008. En SQL Server 2008 Enterprise, el optimizador de consultas tiene en cuenta de forma automática la vista indizada. Para utilizar una vista indizada en el resto de ediciones, es preciso utilizar la sugerencia de tabla NOEXPAND.

Directrices para diseñar una vista indizada

El mejor rendimiento de las vistas indizadas se obtiene cuando se actualizan los datos subyacentes con frecuencia. El mantenimiento de una vista indizada puede ser superior al costo de mantenimiento de un índice de tabla. Si se actualizan frecuentemente los datos subyacentes, el costo de mantener la vista indizada puede no compensar las ventajas que se obtienen en el rendimiento al utilizarla. Si los datos subyacentes se actualizan periódicamente en lotes pero se tratan básicamente como de sólo lectura entre las actualizaciones, considere la posibilidad de eliminar todas las vistas indizadas antes de actualizar y, posteriormente, vuelva a crearlas. Este procedimiento puede mejorar el rendimiento de las actualizaciones.

Las vistas indizadas mejoran el rendimiento de los siguientes tipos de consultas:

  • Las combinaciones y agregaciones que procesan muchas filas.

  • Las operaciones de combinación y agregación realizadas frecuentemente por muchas consultas.

    Por ejemplo, en una base de datos de proceso de transacciones en línea (OLTP) que registra inventarios, se espera que muchas consultas combinen las tablas ProductMaster, ProductVendor y VendorMaster. Aunque las consultas que realizan esta combinación no procesen muchas filas cada una, el proceso de combinación general de cientos de miles de estas consultas puede ser significativo. Puesto que no es probable que estas relaciones se actualicen frecuentemente, el rendimiento global del sistema se puede mejorar con sólo definir una vista indizada que almacene los resultados combinados.

  • Las cargas de trabajo de la ayuda a la toma de decisiones.

    Los sistemas de análisis se caracterizan por la capacidad de almacenar datos agregados resumidos que no se actualizan con frecuencia. La posterior agregación de datos y combinación de muchas filas caracteriza a muchas consultas de ayuda a la toma de decisiones. Además, los sistemas de ayuda a la toma de decisiones contienen ocasionalmente tablas anchas con muchas columnas o columnas que son muy grandes, o ambas cosas a la vez. Las consultas que hacen referencia a un subconjunto estrecho de estas columnas pueden aprovecharse de una vista indizada que sólo incluye las columnas de la consulta, o bien un superconjunto estrecho de estas columnas. La creación de vistas indizadas estrechas que contienen un subconjunto de las columnas de una sola tabla se conoce como estrategia de partición vertical porque divide las tablas verticalmente. Por ejemplo, suponga la existencia de la siguiente tabla y vista indizada:

    CREATE TABLE wide_tbl(a int PRIMARY KEY, b int, ..., z int)
    CREATE VIEW v_abc WITH SCHEMABINDING AS
    SELECT a, b, c
    FROM dbo.wide_tbl
    WHERE a BETWEEN 0 AND 1000
    CREATE UNIQUE CLUSTERED INDEX i_abc ON v_abc(a)
    

    La siguiente consulta puede responderse utilizando únicamente v_abc:

    SELECT b, count_big(*), SUM(c)
    FROM wide_tbl 
    WHERE a BETWEEN 0 AND 1000
    GROUP BY b
    

    La vista v_abc ocupa muchas páginas menos que la tabla wide_tbl. Por lo tanto, será mucho mejor para el optimizador elegirla como ruta de acceso para resolver la consulta anterior.

    Si desea dividir verticalmente una tabla entera en lugar de sólo uno de sus subconjuntos, es aconsejable utilizar un índice no agrupado en la tabla que use la cláusula INCLUDE para incluir únicamente las columnas que desee, en lugar de una vista indizada. Para obtener más información, vea CREATE INDEX (Transact-SQL).

Las vistas indizadas no suelen mejorar el rendimiento de los siguientes tipos de consultas:

  • Los sistemas OLTP con muchas escrituras.

  • Las bases de datos con muchas actualizaciones.

  • Las consultas que no incluyen agregaciones ni combinaciones.

  • Las agregaciones de datos con un alto grado de cardinalidad para la clave GROUP BY. Un alto grado de cardinalidad significa que la clave contiene muchos valores diferentes. Una clave única tiene el grado más alto de cardinalidad ya que cada clave tiene un valor diferente. Las vistas indizadas mejoran el rendimiento mediante la reducción del número de filas a las que tiene acceso una consulta. Si el conjunto de resultados de la vista tiene casi tantas filas como la tabla base, lo que se gana en rendimiento con respecto a la utilización de la vista es mínimo. Por ejemplo, suponga que se realiza la siguiente consulta en una tabla con 1.000 filas:

    SELECT PriKey, SUM(SalesCol)
    FROM ExampleTable
    GROUP BY PriKey
    

    Si la cardinalidad de la clave de tabla es 100, una vista indizada que se genere mediante el resultado de esta consulta sólo tendrá 100 filas. Las consultas que utilizan la vista necesitarán una décima parte de las lecturas necesarias para la tabla base. Si la clave es única, la cardinalidad de la clave es 1000 y el conjunto de resultados de la vista devuelve 1000 filas. Si la vista y la tabla base ExampleTable tienen filas del mismo tamaño, el rendimiento de una consulta no mejora utilizando esta vista indizada en lugar de leer directamente la tabla base.

  • Las combinaciones expandidas. Se trata de vistas cuyos conjuntos de resultados son mayores que los datos originales de las tablas base.

Combinar vistas indizadas con consultas

Aunque las restricciones de los tipos de vistas que pueden indizarse pueden impedir diseñar una vista que resuelva completamente un problema, cabe la posibilidad de diseñar varias vistas indizadas más pequeñas que aceleren partes del proceso.

Considere los ejemplos siguientes:

  • Una consulta de ejecución frecuente que agrega datos a una primera base de datos, luego agrega datos a otra base de datos y, finalmente, combina los resultados. Puesto que una vista indizada no puede hacer referencia a tablas de más de una base de datos, no se puede diseñar una vista única para todo el proceso. Se puede, no obstante, crear una vista indizada en cada base de datos que realice la agregación pertinente. Si el optimizador puede hacer coincidir las vistas indizadas con las consultas existentes, al menos se acelerará el proceso de agregación sin necesidad de volver a codificar las consultas existentes. Aunque la consulta global es más rápida que el proceso de combinación porque utiliza las agregaciones almacenadas en las vistas indizadas.

  • Una consulta de ejecución frecuente que agrega datos de varias tablas y, a continuación, utiliza UNION para combinar los resultados. No se permite utilizar UNION en una vista indizada. Se puede volver a diseñar vistas para realizar cada una de las operaciones individuales de agregación. El optimizador puede seleccionar a continuación las vistas indizadas para acelerar las consultas sin necesidad de volver a codificarlas. Si bien no se mejora el procesamiento UNION, sí se mejoran los procesos individuales de agregación.

Diseñe vistas indizadas que puedan satisfacer varias operaciones. Como el optimizador puede utilizar una vista indizada aunque no está especificada en la cláusula FROM, una vista indizada bien diseñada puede acelerar el procesamiento de muchas consultas.

Por ejemplo, considere la posibilidad de crear un índice en la siguiente vista:

CREATE VIEW ExampleView WITH SCHEMABINDING
AS
SELECT GroupKey, SUM(Colx) AS SumColx, COUNT_BIG(Colx) AS CountColx
FROM MyTable
GROUP BY GroupKey

Esta vista no sólo puede satisfacer consultas que hagan referencia directa a las columnas de la vista, sino que también puede utilizarse para satisfacer consultas que se realizan en la tabla base y contienen expresiones como SUM(Colx), COUNT_BIG(Colx), COUNT(Colx) y AVG(Colx). Todas estas consultas serán más rápidas porque sólo deben recuperar un número reducido de filas de la vista, en lugar de leer el número total de filas de las tablas base.

De forma similar, una vista indizada que agrega datos y grupos cada día puede utilizarse para satisfacer las consultas que se agregan durante distintos intervalos de más de 1 día, por ejemplo 7, 30 ó 90 días.