Comportamiento extraño con columnas calculadas en SQL-Server

12

Mientras leía mi libro de examen 70-433, pensé en algo que veo que no funciona, pero creo que sí. El pasaje decía algo como:

La columna también debe marcarse como PERSISTED , lo que significa que SQL Server almacena físicamente el resultado de la expresión de la columna calculada en la fila de datos en lugar de calcularla cada vez que se hace referencia en una consulta.

De esto entiendo dos cosas:

  1. Una columna calculada no persistente se calcula cada vez que se hace referencia en una consulta
  2. Como no se almacena nada para la columna calculada, supongo que no se puede crear ningún índice para la columna.

Después de leerlo, pensé que esto era un poco extraño, ya que logré crear un índice en una columna no persistente en un proyecto anterior.

¿Cómo se puede crear un índice para algo que no persiste y es perjudicial a largo plazo?


Para probar esto, he ejecutado la siguiente instrucción SQL:

CREATE TABLE testTable
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    telephone VARCHAR(14),
    c_areaCode AS (SUBSTRING(telephone,0,5)),
    cp_areaCode AS (SUBSTRING(telephone,0,5)) PERSISTED
)

INSERT INTO testTable VALUES('09823 000000');
INSERT INTO testTable VALUES('09824 000000');
INSERT INTO testTable VALUES('09825 000000');

CREATE NONCLUSTERED INDEX IX_NotPersisted ON testTable(c_areaCode);
CREATE NONCLUSTERED INDEX IX_Persisted ON testTable(cp_areaCode);

Y luego ejecute las siguientes consultas:

DBCC FREEPROCCACHE
DBCC FREESYSTEMCACHE('ALL');
DBCC DROPCLEANBUFFERS
GO
SELECT cp_areaCode FROM testTable;
GO
SELECT c_areaCode FROM testTable;

Después de mirar el plan de consulta para el código anterior, puedo ver que ambas consultas de selección utilizan el índice no persistente. De nuevo, como?

ingrese la descripción de la imagen aquí

Stuart Blackler
fuente
Para aquellos que tienen el libro 70-433, el texto citado se encuentra en la parte superior de la página 111.
Stuart Blackler

Respuestas:

9

2. Debido a que no hay nada almacenado para la columna calculada, supongo que no se puede crear ningún índice para la columna.

Esta suposición no es cierta, cualquiera de los dos tipos puede indexarse . La columna calculada debe ser determinista en cualquier caso, pero cuando la columna calculada persiste, el requisito de que el cálculo también sea preciso es relajado (es decir, puede implicar operaciones de punto flotante).

¿Cómo se puede crear un índice para algo que no persiste y es perjudicial a largo plazo?

El resultado de la función es "persistente" en el índice en cualquier caso; la única diferencia es si se conserva en la tabla.

Jack dice que intente topanswers.xyz
fuente