SQL Server, y la gran mayoría de motores de bases de datos, no son muy buenas en estimar la cardinalidad para una expresión. No me refiero al valor de una columna, si no al valor de una expresión.
Es aconsejable para el buen entendimiento de este “Tema:III” sobre la Computed Columns, que se lea o repase el enlace: Query Optimizer. Cardinality Estimation Error. SQL Server. Tema: II
Hay varios componentes de SQL Server, que no tiene buen soporte de estadísticas. Por ejemplo, expresiones de este tipo:
Select * from Tutabla Where CampoA * CampoB > 25000
Si observamos, sus planes de ejecución, veremos que no coinciden y pueden llegar a ser muy distantes los números reales de registros devueltos a los números estimados de registros a devolver. Lo que lleva al Optimizador de Consultas a realizar planes de ejecución sin calidad.
Para estos casos, y poder obtener un mejor performance en las consultas, se recomienda añadir un nuevo campo a la tabla, este campo no será una columna normal, en lugar de decir que esa de un tipo de dato concreto, indicaremos una expresión. Por ejemplo:
ALTER TABLE Tutabla
ADD cc AS CampoA * CampoB
Con lo anterior expuesto, vamos a obtener un nuevo campo (cc) en nuestra tabla, cuyo resultado será la expresión: CampoA * Campo. El beneficio que obtenemos al realizar esto, es que SQL Server, nos puede dar soporte de estadísticas para este nuevo campo. Estas estadísticas se usarán para que el Optimizador de Consulta tome una mejor decisión a la hora de crear el plan de ejecución.
Una vez, realizado el: ALTER TABLE Tutabla ADD cc AS CampoA * CampoB, si después ejecutamos la consulta: Select * from Tutabla Where CampoA * CampoB > 25000, veremos que con casi tuda seguridad, los números estimados de registros a devolver (en su plan de ejecución), se aproximan mucho mas, a los números reales de registros devueltos, lo que conllevará a facilitar para que el Optimizador generé mejores planes de ejecución.
Para obtener los beneficios de estas Computer Columns (Columnas Calculadas). Tenemos que usar la misma expresión y en el mismo orden, en el Where, tal cual la hemos definido en la tabla. Para nuestro caso de ejemplo: CampoA * CampoB
No mejoraría nuestro performance, ya que para SQL Server la expresión no es la misma, y no nos estaríamos aprovechando de las estadísticas para el caso: Select * from Tutabla Where CampoB * CampoA > 25000, ya que tenemos invertidos los nombres de las columnas.
La forma correcta sería: Select * from Tutabla Where CampoA * CampoB > 25000, pero también podemos utilizar el nombre de la columna, de la forma: Select * from Tutabla Where cc > 25000. Hay un beneficio en utilizar la expresión (CampoA * CampoB) en lugar del campo de la tabla (cc), ya que si nosotros tenemos esta expresión en nuestras aplicaciones (supongamos que en muchos lugares), no es necesario cambiar nada de código en dichas aplicaciones, SQL Server automáticamente detecta la expresión y la tratará como Computer Columns.
Los datos/campos para calcular el resultado, del campo calculado, han de proceden de la misma tabla.
Desde la versión de SQL Server 2005 y en adelante, tenemos disponible la propiedad en los Campos Calculados de "Persistentes". Esta propiedad es aconsejable si las tablas son muy grandes. Si activamos las Computed Columns como "Persistente", entonces los datos de columna calculada se almacenan en el disco. Mientras que si no esta activa, entonces la columna calculada será sólo una columna virtual y los valores se calculan cada vez que se las hace referencia. Si no es imprescindible, no persistas la información. Estas columnas se sincronizarán automáticamente si se actualiza cualquier campo de los que haga referencia. Un beneficio adicional es que también podemos crear un índice, en esta columna calculada, como por ejemplo, de la forma:
CREATE INDEX IX_cc on Tutabla (cc)
Este índice, nos proporcionara beneficios adicionales como por ejemplo encontrar los registros más rápidamente.
Se aconseja leer: Actualización de estadísticas síncronas o asíncronas mejoran la respuesta del optimizador de consultas. SQL Server
Fuentes:
Microsoft, MSDN, Benjamin Nevares
Apunte y recopilación por Norman M. Pardell
Puedes consultarme, si deseas cualquier aclaración, pregunta o sugerencia en: Contacto, contestaré tan pronto como me sea posible.