Vistas indexadas en SQL Server

Básicamente, una vista indexada (o indizada) es una vista que ha «materializado» un conjunto de valores únicos en forma de índice agrupado. Otro nombre que toman estas vistas viene de ahí precisamente: vistas materializadas, el cual es el nombre que toman en SGBDs como Oracle. Su ventaja es que proporcionan una búsqueda rápida de obtener información desde una vista. Tras el primer índice, el cual ha de ser agrupado de un conjunto único de valores, podemos crear índices adicionales sobre la vista usando la clave agrupada del primer índice como punto de referencia. De todas formas, este tipo de vistas tiene una serie de restricciones sobre cuándo podemos y cuando no crear índices sobre las vistas. Se muestran a continuación:

– La vista ha de usar la opción SCHEMABINDING

– Si hace referencia a cualquier función definida por el usuario, entonces debe tener un esquema enlazado

– La vista no puede hacer referencia a ninguna otra vista, sólo a tablas y a funciones definidas por el usuario (UDF)

– Todas las tablas y UDF referenciadas en la vista deben utilizar un convenio de denominación de nombres compuestos de varias partes (dbo.Customers, usuario.MiUDF) y tener el mismo propietario que la vista.

– Debe estar en la misma base de datos que los objetos a los que referencia

– Las opciones ANSI_NULLS y QUOTED_IDENTIFIER deben estar activadas (por ejemplo, SET ANSI_NULLS ON) en el momento en que se cree la vista y todas las tablas subyacentes.

– Cualquier función a la que haga referencia la vista ha de ser determinista

– No podemos usar OUTER JOINS, únicamente INNER JOINS

Veamos un ejemplo:

CREATE VIEW VISTA_PEDIDOSCLIENTES

WITH SCHEMABINDING

AS

SELECT cu.CompanyName,

o.OrderId,

o.OrderDate,

od.ProductID,

p.ProductName,

od.Quantity,

od.UnitPrice

FROM dbo.Customers as cu

INNER JOIN dbo.Orders AS o ON cu.CustomerID=o.CustomerID

INNER JOIN dbo.[Order Details] AS od ON o.OrderID=od.OrderID

INNER JOIN dbo.Products AS P on od.Producto=p.ProductID

Con esto aun no tenemos una vista indexada, sino una vista que se puede indexar. Cuando creamos el índice, el primero ha de ser agrupado y único:

CREATE UNIQUE CLUSTERED INDEX IDX_CLIENTES_PEDIDOS

ON VISTA_CLIENTES_PEDIDOS(CompanyName, OrderID, ProductID)

Una vez ejecutado este comando, ya tendremos una vista agrupada. Esta vista se ha hecho sobre la base de datos Northwind (en diferentes versiones de SQL Server no aparece, pero puede importarse de otras versiones). Si ahora hacemos un select de todos los campos sobre esta vista y echamos un ojo al plan de ejecución, veremos que no ha utilizado para nada el índice que le acabamos de proporcionar.

El problema viene del tamaño de las tablas, ya que la base de datos no tiene suficientes datos. El optimizador hace un balance entre lo que puede tardar en ejecutarse el primer plan que encuentra y la cantidad de trabajo requerido para seguir buscando un plan mejor. Por ejemplo ¿tiene sentido tardar más de dos segundos en pensar un plan cuando el plan conocido se puede realizar en menos de un segundo?

En este caso, SQL Server observa la tabla subyacente, comprueba que no existen muchos datos y decide que el plan que tiene es «suficientemente bueno» antes de que el optimizador pueda comprobar que el índice de la vista podría ser más rápido. Este problema de «cuantos datos hay» frente a «lo que cuesta seguir buscando un plan mejor» lo debemos tener en cuenta al crear cualquier índice, no sólo para los de vistas. En los conjuntos de datos pequeños, existe una gran probabilidad de que SQL Server ignore totalmente nuestro índice a favor del primer plan que encuentre. En este caso, pagamos el costo de mantener el índice (ejecuciones más lentas de INSERT, UPDATE Y DELETE) sin obtener ningún beneficio en la instrucción SELECT.

Una de las ventajas de las vistas indexadas radica en que mejoran el rendimiento de operaciones de combinación y agregación. Si realizamos frecuentemente este tipo de operaciones, la vista indexada por su naturaleza nos permite tener el resultado obtenido de forma directa sin ningún cálculo, en contraposición a una consulta que tuviera que realizar todas esas operaciones en el momento.

Volvamos al tema del rendimiento, para poder ver la diferencia entre una cantidad pequeña de registros y una grande, podemos descargar y ejecutar una secuencia de comandos denominada CreateAndLoadNorthwindBulk.sql la cual se puede encontrar en:

http://media.wiley.com/product_ancillary/92/07645437/DOWNLOAD/4486.zip

Este script nos crea una réplica mucho más grande de Northwind. Ahora podemos volver a crear nuestra vista e índice para esa base de datos. Si comprobamos esta vez el nuevo plan de ejecución veremos que esta vez sí acepta la vista indexada que existe en nuestra tabla. El rendimiento total de esta vista es ahora mucho más rápido fila por fila de lo que hubiera sido el modelo anterior.

 

* Transcripción del libro Fundamentos Programación con SQL Server 2005 de Robert Vieira

Deja una respuesta