세션 레벨 임시 테이블이 아닌 전역 임시 테이블에 대한 논리적 읽기


11

다음과 같은 간단한 MCVE를 고려하십시오.

SET STATISTICS IO, TIME OFF;
USE tempdb;

IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
CREATE TABLE #t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
CREATE TABLE ##t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
CREATE TABLE dbo.s1 
(
    r int NOT NULL
        PRIMARY KEY CLUSTERED
);

INSERT INTO dbo.s1 (r)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc1
    CROSS JOIN sys.syscolumns sc2;
GO

다음 삽입을 실행하면에 삽입 #t1하면 임시 테이블에 대한 통계 I / O가 표시되지 않습니다. 그러나에 삽입 하면 임시 테이블에 대한 통계 I / O ##t1 표시됩니다.

SET STATISTICS IO, TIME ON;
GO

INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;

통계 출력 :

SQL Server 구문 분석 및 컴파일 시간 : 
   CPU 시간 = 0ms, 경과 시간 = 1ms
테이블 's1'. 스캔 카운트 1, 논리적 읽기 19, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.

 SQL Server 실행 시간 :
   CPU 시간 = 16ms, 경과 시간 = 9ms

(10000 개의 행이 영향을 받음)
INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;
SQL Server 구문 분석 및 컴파일 시간 : 
   CPU 시간 = 0ms, 경과 시간 = 1ms
테이블 '## t1'. 스캔 카운트 0, 논리적 읽기 10016, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.
테이블 's1'. 스캔 카운트 1, 논리적 읽기 19, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.

 SQL Server 실행 시간 :
   CPU 시간 = 47ms, 경과 시간 = 45ms

(10000 개의 행이 영향을 받음)

삽입 할 때 ## temp 테이블에 너무 많은 읽기가있는 이유는 무엇입니까?

답변:


11

INSERT INTO및 전역 임시 테이블을 사용할 때 최소 로깅이 사용되지 않습니다

다음을 사용하여 전역 임시 테이블에 백만 개의 행 삽입 INSERT INTO

INSERT INTO ##t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

SELECT * FROM fn_dblog(NULL, NULL)위 쿼리가 실행 되는 동안 실행하면 ~ 1M 개의 행이 반환됩니다.

여기에 이미지 설명을 입력하십시오

LOP_INSERT_ROW각 행마다 하나의 작업 + 다른 로그 데이터


로컬 임시 테이블에 동일한 삽입

INSERT INTO #t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

700 행까지만 반환 SELECT * FROM fn_dblog(NULL, NULL)

여기에 이미지 설명을 입력하십시오

최소 로깅


다음을 사용하여 전역 임시 테이블에 백만 개의 행 삽입 SELECT INTO

SELECT top(1000000) s1.r
INTO ##t2
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

여기에 이미지 설명을 입력하십시오

SELECT INTO 10k 레코드가있는 전역 임시 테이블

SELECT s1.r
INTO ##t2
FROM dbo.s1;

시간 및 IO 통계

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 16 ms,  elapsed time = 10 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

이 블로그 게시물 을 기반으로 TABLOCK힙 테이블에서 최소 로깅을 시작하도록 추가 할 수 있습니다.

INSERT INTO ##t1 WITH(TABLOCK) (r)
SELECT   s1.r
FROM dbo.s1

낮은 논리적 읽기

Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(10000 rows affected)

임시 테이블에서 최소한의 로깅을 달성하는 방법에 대한 @PaulWhite 의 답변 중 일부

아니요. 로컬 임시 테이블 (#temp)은 생성 세션 전용이므로 테이블 잠금 힌트가 필요하지 않습니다. tempdb에서 작성된 전역 임시 테이블 (## temp) 또는 일반 테이블 (dbo.temp)에는 테이블 잠금 힌트가 필요합니다. 여러 테이블에서 액세스 할 수 있기 때문입니다.

이것을 테스트하기 위해 일반 테이블 만들기 :

CREATE TABLE dbo.bla
(
    r int NOT NULL 
);

1M 레코드로 채우기

INSERT INTO bla 
SELECT   top(1000000)s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

이 테이블에서 1M 이상의 논리적 읽기

Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

글로벌 임시 테이블에보고 된 논리적 읽기를 설명하는 Paul White의 답변

일반적으로 삽입이 최소로 기록되지 않은 경우 대상 테이블에 대한 논리적 읽기가보고됩니다.

이러한 논리적 읽기는 기존 구조에서 새 행을 추가 할 위치를 찾는 것과 연관됩니다. 최소로 기록 된 삽입물은 벌크 로딩 메커니즘을 사용하여 완전히 새로운 페이지 / 확장자를 할당하므로 동일한 방식으로 대상 구조를 읽을 필요가 없습니다.


결론

결론은 INSERT INTO최소 로깅을 사용할 수 없으므로 전역 임시 테이블 / 일반 테이블과 함께 사용될 때 tempdb의 로그 파일에 삽입 된 모든 행을 개별적으로 로깅합니다. 로컬 임시 테이블 / SELECT INTO/ INSERT INTO ... WITH(TABLOCK)은 최소 로깅을 사용할 수 있습니다.

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