Просто для узагальнення експериментальних висновків у коментарях це здається кращим випадком, який виникає, коли у вас є дві обчислені колонки в одній таблиці, одна persisted
і одна не зберігаються, і вони мають однакове визначення.
У плані запиту
SELECT id5p
FROM dbo.persist_test;
Сканування таблиці persist_test
видає лише id
стовпець. Наступний скаляр обчислень помножує на 5 і виводить стовпчик, що викликається, id5
незважаючи на те, що цей стовпець навіть не посилається в запиті. Кінцевий скаляр обчислення вздовж приймає значення id5
та виводить, що називається стовпцем id5p
.
Використання прапорів слідів, пояснених в Deep Dive Dive 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
і він обчислює значення, незважаючи на збереження.