Las vistas son tablas virtuales que nos devuelven datos de una consulta sobre una o varias tablas. Igual que una tabla tiene sus columnas y sus filas pero al contrario que estas ese conjunto de datos como tal no está almacenado en ningún sitio. Cada tabla tiene sus datos y la vista los lee de ahí. Entonces, ¿los resultados de datos de las vistas no se guardan en ningún sitio? En realidad hay algunos tipos de vistas que sí guardan los datos finales como es el caso de las vistas materializadas que implementan algunos gestores de bases de datos (Oracle, por ejemplo). En el caso de SQL Server este tipo de vista no está disponible, aunque no podemos descartar que se implemente en un futuro (en Azure Synapse Analytics han existido desde siempre).
¿Qué alternativa tenemos en SQL Server?
Como hemos visto antes, las vistas las vemos como si fueran una tabla pero en realidad no tienen datos, los recuperan dinámicamente de las tablas a las que se referencia. Esto es muy útil en la mayoría de los casos ya sea por simplicidad de las consultas, para abstraernos de la estructura original y simplificar la estructura saliente o para gestionar permisos. Sin embargo el uso de una vista no afecta en nada al rendimiento pues ejecuta la consulta tal cual como si la escribiéramos a mano. Si una vista lee sobre varias tablas grandes generará mucho consumo de E/S y si la definición de la vista incluye procesamientos complejos y muchas uniones entre tablas tendremos una notoria degradación de rendimiento.
Como alternativa, en SQL Server podemos hacer uso de un tipo de vista especial que son las Vistas Indexadas (o indizadas), son vistas que tienen un índice clustered por lo que si van a almacenar el conjunto de resultados en la base de datos para poder hacer una lectura plana.
Dónde usar las vistas indexadas
Las vistas indexadas ofrecen un rendimiento de lecturas mejorado al hacer uso del índice para leer los datos y no tener que ejecutar la consulta subyacente. Sin embargo, nos pueden llegar a penalizar considerablemente las operaciones de escritura al añadir no sólo otro índice donde escribir los datos sino complejidad a ese índice. Adicionalmente podremos crear tantos índices nonclustered sobre la vista como necesitemos. Al igual que ocurre con los índices de las tablas en nuestra mano queda medir el coste/beneficio y valorar su idoneidad.
Con las vistas indexadas notaremos una mejora sustancial en el rendimiento de nuestras consultas si las aplicamos sobre entornos con una gran diferencia de lecturas frente a escrituras, se me viene a la cabeza sobre todo entornos Data Warehouse, bases de datos OLAP o entornos de minería de datos. Rara vez serán recomendables en entornos con alta carga de transacciones IUD (insert, update y delete) en bases de datos OLTP.
Limitaciones de las vistas indexadas
Como ya hemos visto uno de los inconvenientes de las vistas indexadas es que la degradación en rendimiento de las escrituras es mayor que la mejora en las lecturas, esto nos limita en gran medida su uso. Sin embargo no es su única limitación, la verdad es que tienen una amplia lista de incompatibilidades y requisitos. Uno de los principales requisitos de las vistas indexadas es que hay que crearlas con la opción SCHEMABINDING esto implica que no se podrán modificar las tablas referenciadas.
Consideraciones para crear vistas indexadas
Además de tener que crear la vista como SCHEMABINDING tenemos que tener en cuenta otros aspectos importantes:
- Las vistas indexadas no admiten expresiones no deterministas. Es decir, las expresiones de la vista siempre deben devolver el mismo resultado no como GETDATE() que nos devolvería un valor distinto en cada ejecución.
- Las tablas y funciones dentro de la vista deben declararse con el nombre completo (esquema.tabla).
- No se admiten subconsultas.
- No se admiten OUTER JOINS, esto deja fuera RIGHT JOIN y LEFT JOIN.
- El índice clustered de nuestra vista ocupará espacio en disco.
- Solo se puede hacer referencia a tablas de la misma base de datos.
- Si tenemos GROUP BY, la definición de la vista debe contener COUNT_BIG(*), pero no HAVING.
- No se puede usar EXISTS, NOT EXISTS, COUNT(*), MIN, MAX, hints de tablas, TOP ni UNION.
- No puede utilizar los tipos de datos text, ntext , image o XML. El tipo de datos float se puede utilizar en la vista, pero no en el índice agrupado
Como crear vistas indexadas
Para crear una vista indexada lo primero que haremos será crear la vista con la opción SCHEMABINDING
CREATE VIEW VI_Facturas_Ventas
WITH SCHEMABINDING AS
SELECT FC.cliente, FD.Articulo, COUNT_BIG(*)
FROM Ventas.FacturasCabeceras FC
INNER JOIN Ventas.FacturasDetalle FD
ON FC.NumFactura = FD.NumFactura
GROUP BY FC.cliente, FD.Articulo
Una vez que tenemos creada la vista tendremos que crear el índice clustered.
CREATE UNIQUE CLUSTERED INDEX CI_Facturas_Ventas ON VI_Facturas_Ventas (Cliente, Articulo);
En este punto el optimizador de consultas podrá usar nuestro índice para cualquier consulta sobre la tabla, incluso para consultas sobre las tablas sin que se use la vista aunque, esto último, sólo en ediciones Enterprise de SQL Server.
Conclusiones
Un gran poder conlleva una gran responsabilidad y las vistas indexadas son una increíble herramienta en entornos o tablas con gran cantidad de lectura y pocas modificaciones pero si no es así nos pueden hacer mucho daño al servidor. El uso de vistas indexadas de SQL Server puede ser una buena técnica para mejorar el rendimiento de las consultas al reducir el costo de E/S y la duración de las consultas, pero requiere pruebas, planificación y un estudio pormenorizado de donde usar vistas indexadas. Se debe realizar un análisis completo del impacto en el rendimiento, midiendo las mejoras en el rendimiento de lecturas frente al coste en las escrituras.


[…] sobre una tabla HEAP o una vista que no tenga un índice clustered (más sobre vistas indexadas aquí) el nivel de hoja contendrá el RID (identificador de fila) de las filas además de las columnas […]
[…] modificar estas sugerencias para adaptarlos a nuestro escenario. No tenemos que olvidar tampoco las vistas indexadas para tener índices que nos cubran consultas más complejas con uniones entre […]
[…] FullText. Tenemos que saber que podemos crear índices de texto completo tanto en tablas como en vistas indexadas pero solo uno por tabla (o vista). El índice de cada tabla podrá contener hasta 1024 columnas. La […]
[…] almacenan información sobre la distribución de los valores en una o más columnas de una tabla o vista indexada. Cada objeto de estadísticas está compuesto por un histograma que describe la distribución de […]