Nur um die experimentellen Ergebnisse in den Kommentaren zusammenzufassen, scheint dies ein Randfall zu sein, der auftritt, wenn Sie zwei berechnete Spalten in derselben Tabelle haben, eine persisted
und eine nicht beibehalten und beide dieselbe Definition haben.
Im Plan für die Abfrage
SELECT id5p
FROM dbo.persist_test;
Der Table Scan on persist_test
gibt nur die id
Spalte aus. Der nächste Berechnungsskalar multipliziert dies mit 5 und gibt eine aufgerufene Spalte aus, id5
obwohl in der Abfrage nicht einmal auf diese Spalte verwiesen wird. Der endgültige Berechnungsskalar nimmt den Wert von id5
und gibt diesen als aufgerufene Spalte aus id5p
.
Verwenden der in Query Optimizer Deep Dive - Teil 2 erläuterten Ablaufverfolgungsflags (Haftungsausschluss: Diese Ablaufverfolgungsflags werden nicht dokumentiert / nicht unterstützt) und Betrachten der Abfrage
SELECT id5,
id5p,
( id * 5 )
FROM dbo.persist_test
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
Gibt die Ausgabe aus
Baum vor Projektnormalisierung
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)
Baum nach Projektnormalisierung
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
Es sieht also so aus, als würden alle berechneten Spaltendefinitionen während der Phase der Projektnormalisierung erweitert und alle identischen Ausdrücke wieder mit berechneten Spalten abgeglichen, was id5
in diesem Fall einfach zutrifft . dh die persisted
Spalte wird nicht bevorzugt .
Wenn die Tabelle mit der folgenden Definition neu erstellt wird
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
Dann wird eine Anfrage für entweder id5
oder id5p
wird beim Lesen der persistente Version der Daten erfüllt werden , anstatt die Berechnung zur Laufzeit zu tun , um die passenden (zumindest in diesem Fall) zu passieren scheint in Spaltenreihenfolge.
[tempdb].[dbo].[persist_test].id
und der Wert berechnet, obwohl er beibehalten wird.