주석의 실험 결과를 요약하면 동일한 테이블에 두 개의 계산 열이 persisted
있고 하나는 유지되지 않고 둘 다 동일한 정의 를 가질 때 발생하는 가장 큰 경우 인 것 같습니다 .
쿼리 계획에서
SELECT id5p
FROM dbo.persist_test;
테이블 스캔 persist_test
은 id
열만 방출합니다 . 다음 계산 스칼라는이 값에 5를 곱하고이 id5
열이 쿼리에서 참조되지 않더라도 호출 된 열을 출력 합니다. 최종 계산 스칼라는 함께 값을 id5
이라는 열로 출력합니다 id5p
.
Query Optimizer Deep Dive – Part 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
유지되며 계속 유지되지만 값을 계산합니다.