Просто для подведения итогов экспериментальных результатов в комментариях, это, кажется, крайний случай, который возникает, когда у вас есть два вычисляемых столбца в одной таблице, один persisted
и один не сохраняются, и оба имеют одно и то же определение.
В плане запроса
SELECT id5p
FROM dbo.persist_test;
При сканировании таблицы persist_test
генерируется только id
столбец. Следующий вычисляющий скаляр умножает это на 5 и выдает столбец, вызываемый id5
несмотря на то, что на этот столбец даже нет ссылки в запросе. Финальный скаляр вычислений принимает значение id5
и выводит его как вызванный столбец id5p
.
Использование флагов трассировки, описанных в Query Optimizer Deep Dive - часть 2 (отказ от ответственности: эти флаги трассировки не документированы / не поддерживаются) и анализ запроса
SELECT id5,
id5p,
( id * 5 )
FROM dbo.persist_test
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
Дает вывод
Дерево перед нормализацией проекта
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)
Дерево после нормализации проекта
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
Таким образом, получается, что все определения вычисляемых столбцов расширяются, а затем на этапе нормализации проекта все идентичные выражения сопоставляются с вычисляемыми столбцами, и id5
в этом случае это просто совпадает . то есть это не дает никакого предпочтения persisted
колонке.
Если таблица воссоздается со следующим определением
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5p AS (5 * id) PERSISTED
, id5 AS (5 * id)
);
Затем запрос либо id5
или id5p
будет удовлетворен, читая сохраненную версию данных , а не делать расчет во время выполнения , поэтому согласование , как представляется , произойдет (по крайней мере , в данном случае), чтобы колонки.
[tempdb].[dbo].[persist_test].id
и он вычисляет значение, несмотря на то, что он сохранен.