지속 형 계산 열을 선택할 때 SQL Server가 "계산 스칼라"인 이유는 무엇입니까?


21

SELECT이 코드 의 세 문장

USE [tempdb];
GO

SET NOCOUNT ON;

CREATE TABLE dbo.persist_test (
      id            INT NOT NULL
    , id5           AS (id * 5)
    , id5p          AS (id * 5) PERSISTED
);

INSERT INTO dbo.persist_test (id)
VALUES (1), (2), (3);

SELECT id
FROM dbo.persist_test;

SELECT id5
FROM dbo.persist_test;

SELECT id5p
FROM dbo.persist_test;

DROP TABLE dbo.persist_test;

이 계획을 생성하십시오.

실행 계획

SELECT지속 값을 선택하는 final 이 Compute Scalar 연산자를 생성하는 이유는 무엇 입니까?


3
여기 @SqlKiwi의 답변을 참조하십시오. 왜 실행 계획에 지속되는 계산 열에 대한 사용자 정의 함수 호출이 포함됩니까? . 쿼리에서 테이블의 출력 열 목록은 단지 [tempdb].[dbo].[persist_test].id유지되며 계속 유지되지만 값을 계산합니다.
Martin Smith

답변:


14

주석의 실험 결과를 요약하면 동일한 테이블에 두 개의 계산 열이 persisted있고 하나는 유지되지 않고 둘 다 동일한 정의 를 가질 때 발생하는 가장 큰 경우 인 것 같습니다 .

쿼리 계획에서

SELECT id5p
FROM dbo.persist_test;

테이블 스캔 persist_testid열만 방출합니다 . 다음 계산 스칼라는이 값에 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충족하므로 열 순서로 일치하는 것으로 보입니다 (적어도이 경우).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.