Persisted en campos calculados

Cláusula Persisted en campos calculados en SQL Server

La cláusula Persisted se puede utilizar en la definición de un campo calculado en las tablas de una base de datos en SQL Server.
Los campos calculados en las tablas permiten almacenar los datos que se calculan en base a los campos de la misma tabla. (Ver Campos calculados).

En este artículo se mostrará como al usar la cláusula Persisted en un campo calculado y luego listar y actualizar los registros mostrando el Plan de ejecución estimado tanto en la tabla que tiene la cláusula Persisted como en otra que no se ha utilizado.

Usando Persisted en campos calculados

Usando la base de datos Nortwind, se va a crear dos tablas y copiar los datos de la tabla Products (Productos). En ambas tablas habrá la misma cantidad de registros y los mismos campos, en una de las tablas se usará la clausula Persisted en la creación del campo calculado para el valor del Stock y en otra tabla no se usará Persisted.

use Northwind
go
La tabla siguiente se usará la cláusula Persisted en el campo calculado del Valor del Stock. (Ver Create Table)
Create table ProductosConPersisted
(
ProductosConPersistedCodigo nchar(5),
ProductosConPersistedDescripcion nvarchar(50),
ProductosConPersistedUnidad nvarchar(30),
ProductosConPersistedPrecio Numeric(9,2),
ProductosConPersistedStock Numeric(9,2),
ProductosConPersistedValorStock As (ProductosConPersistedPrecio * ProductosConPersistedStock) Persisted
constraint ProductosConPersistedPK primary key (ProductosConPersistedCodigo)
)
go

La tabla siguiente NO se usará la cláusula Persisted en el campo calculado del Valor del Stock.
Create table ProductosSinPersisted
(
ProductosSinPersistedCodigo nchar(5),
ProductosSinPersistedDescripcion nvarchar(50),
ProductosSinPersistedUnidad nvarchar(30),
ProductosSinPersistedPrecio Numeric(9,2),
ProductosSinPersistedStock Numeric(9,2),
ProductosSinPersistedValorStock As (ProductosSinPersistedPrecio * ProductosSinPersistedStock)
constraint ProductosSinPersistedPK primary key (ProductosSinPersistedCodigo)
)
go

Llenar las tablas con los registros de Products.
Primero la tabla cuyo campo calculado ha sido creado usando la cláusula Persisted. (Ver Insert)

Insert into ProductosConPersisted
select
Right(‘0000’+trim(Str(P.ProductID)),5), P.ProductName,
P.QuantityPerUnit , P.UnitPrice, P.UnitsInStock
from Products As P
go

Segundo la tabla cuyo campo calculado NO ha sido creado usando la cláusula Persisted.
Insert into ProductosSinPersisted
select
Right(‘0000’+trim(Str(P.ProductID)),5), P.ProductName,
P.QuantityPerUnit , P.UnitPrice, P.UnitsInStock
from Products As P
go

Ver los datos de las tablas

Select * from ProductosConPersisted
go

Select * from ProductosSinPersisted
go

Analizando los resultados

Actualizar los datos (Ver Update)

La tabla cuyo campo calculado se incluyó la cláusula Persisted
update ProductosConPersisted
set ProductosConPersistedPrecio = ProductosConPersistedPrecio * 1.1
go

La tabla cuyo campo calculado NO se incluyó la cláusula Persisted
update ProductosSinPersisted
set ProductosSinPersistedPrecio = ProductosSinPersistedPrecio * 1.1
go

Creando índices para cada campo calculado en las tablas. (Ver Índices)

Create index ValorStockConPersistedIDX on
ProductosConPersisted(ProductosConPersistedValorStock)
go
Create index ValorStockSinPersistedIDX on
ProductosSinPersisted(ProductosSinPersistedValorStock)
go

Para analizar el resultado mostrando los registros ordenados por el campo calculado
select * from ProductosConPersisted
order by ProductosConPersistedValorStock desc
go

select * from ProductosSinPersisted
order by ProductosSinPersistedValorStock desc
go

Si visualizamos el espacio ocupados por las tablas podemos notar que la tabla que tiene el campo calculado marcado como Persisted su índice ocupa un mayor espacio que la tabla que no tiene marcado como Persisted el campo calculado.
sp_spaceused ProductosConPersisted
go
sp_spaceused ProductosSinPersisted
go

Por último, una tabla sin campo calculado el cual se presentará al listar los registros.
Create table ProductosSinCalculado
(
ProductosSinCalculadoCodigo nchar(5),
ProductosSinCalculadoDescripcion nvarchar(50),
ProductosSinCalculadoUnidad nvarchar(30),
ProductosSinCalculadoPrecio Numeric(9,2),
ProductosSinCalculadoStock Numeric(9,2),
constraint ProductosSinCalculadoPK primary key (ProductosSinCalculadoCodigo)
)
go

Llenar las tablas con los registros de Products.
Insert into ProductosSinCalculado
select
Right(‘0000’+trim(Str(P.ProductID)),5), P.ProductName,
P.QuantityPerUnit , P.UnitPrice, P.UnitsInStock
from Products As P
go

Listado incluyendo el campo calculado.
select *,
‘Valor del Stock’ = P.ProductosSinCalculadoPrecio * P.ProductosSinCalculadoStock
from ProductosSinCalculado As P
go

Decida usted mismo, la sugerencia es usar los campos calculados para evitar tener que realizar cálculos previos para mostrar los datos totalizados o cuando extraiga información de varias tablas usando Joins (Ver Joins) y necesite el campo calculado.. Evalue siempre las diferentes alternativas.