Solo per riassumere i risultati sperimentali nei commenti, questo sembra essere un caso limite che si verifica quando si hanno due colonne calcolate nella stessa tabella, una persisted
e una non persistente ed entrambe hanno la stessa definizione.
Nel piano per la query
SELECT id5p
FROM dbo.persist_test;
La scansione della tabella attiva persist_test
emette solo la id
colonna. Il successivo scalare di calcolo si moltiplica per 5 e genera una colonna chiamata id5
nonostante il fatto che questa colonna non sia nemmeno citata nella query. Lo scalare di calcolo finale prende il valore id5
e lo emette come una colonna chiamataid5p
.
Utilizzo dei flag di traccia spiegati in Deep Dive di Query Optimizer - Parte 2 (dichiarazione di non responsabilità: questi flag di traccia non sono documentati / non supportati) e osservano la query
SELECT id5,
id5p,
( id * 5 )
FROM dbo.persist_test
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
Fornisce l'output
Albero prima della normalizzazione del progetto
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)
Albero dopo la normalizzazione del progetto
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
Quindi sembra che tutte le definizioni delle colonne calcolate vengano espanse poi durante la fase di normalizzazione del progetto tutte le espressioni identiche vengono ricondotte alle colonne calcolate e id5
in questo caso sembra corrispondere . cioè non dà alcuna preferenza alla persisted
colonna.
Se la tabella viene ricreata con la seguente definizione
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
Quindi una richiesta per uno id5
o id5p
sarà soddisfatta dalla lettura della versione persistente dei dati anziché fare il calcolo in fase di esecuzione in modo che la corrispondenza sembra avvenire (almeno in questo caso) in ordine di colonna.
[tempdb].[dbo].[persist_test].id
e calcola il valore nonostante sia persistente.