Juste pour résumer les résultats expérimentaux dans les commentaires, cela semble être un cas extrême qui se produit lorsque vous avez deux colonnes calculées dans la même table, une persisted
et une non persistante et qu'elles ont toutes les deux la même définition.
Dans le plan de la requête
SELECT id5p
FROM dbo.persist_test;
L'analyse de la table sur persist_test
n'émet que la id
colonne. Le prochain calcul scalaire multiplie cela par 5 et génère une colonne appelée id5
malgré le fait que cette colonne n'est même pas référencée dans la requête. Le scalaire de calcul final prend la valeur de id5
et affiche cette valeur sous la forme d'une colonne appelée id5p
.
Utilisation des indicateurs de trace expliqués dans Query Optimizer Deep Dive - Partie 2 (avertissement: ces indicateurs de trace sont non documentés / non pris en charge) et en regardant la requête
SELECT id5,
id5p,
( id * 5 )
FROM dbo.persist_test
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
Donne la sortie
Arborescence avant la normalisation du projet
LogOp_Project
LogOp_Get TBL: dbo.persist_test dbo.persist_test TableID=1717581157 TableReferenceID=0 IsRow: COL: IsBaseRow1002
AncOp_PrjList
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5p
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
AncOp_PrjEl COL: Expr1004
ScaOp_Arithmetic x_aopMult
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id
ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=5)
Arborescence après la normalisation du projet
LogOp_Project
LogOp_Get TBL: dbo.persist_test dbo.persist_test TableID=1717581157 TableReferenceID=0 IsRow: COL: IsBaseRow1002
AncOp_PrjList
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
AncOp_PrjEl QCOL: [tempdb].[dbo].[persist_test].id5p
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
AncOp_PrjEl COL: Expr1004
ScaOp_Identifier QCOL: [tempdb].[dbo].[persist_test].id5
Il apparaît donc que toutes les définitions de colonnes calculées sont développées, puis pendant la phase de normalisation du projet, toutes les expressions identiques sont mises en correspondance avec les colonnes calculées et il se trouve que cela correspond id5
dans ce cas. c'est-à-dire qu'il ne donne aucune préférence à la persisted
colonne.
Si la table est recréée avec la définition suivante
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
Ensuite, une demande pour id5
ou id5p
sera satisfaite en lisant la version persistante des données plutôt qu'en effectuant le calcul au moment de l'exécution, de sorte que la correspondance semble se produire (au moins dans ce cas) dans l'ordre des colonnes.
[tempdb].[dbo].[persist_test].id
et elle calcule la valeur malgré sa persistance.