次の単純な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が表示されません。ただし、intoを挿入すると、一時テーブルの統計I / O ##t1
が表示されます。
SET STATISTICS IO, TIME ON;
GO
INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;
統計出力:
SQL Serverの解析時間とコンパイル時間: CPU時間= 0 ms、経過時間= 1 ms。 テーブル 's1'。スキャンカウント1、論理読み取り19、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。 SQL Server実行時間: CPU時間= 16 ms、経過時間= 9 ms。 (10000行が影響を受けました)
INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;
SQL Serverの解析時間とコンパイル時間: CPU時間= 0 ms、経過時間= 1 ms。 テーブル '## 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時間= 47 ms、経過時間= 45 ms。 (10000行が影響を受けました)
## tempテーブルに挿入しているだけなのに、なぜ## tempテーブルに非常に多くの読み取りがあるのですか?