派生テーブルは一時テーブルよりもパフォーマンスが優れていますが、とにかく多くのSQL Server開発者は2番目のテーブルを好みます。どうして?大量のデータ(数百万のレコード)でクエリを実行する必要があり、最良の選択を使用していることを確認したい。
CREATE TABLE A(
id BIGINT IDENTITY(1,1) NOT NULL,
field1 INT NOT NULL,
field2 VARCHAR(50) NULL,
);
CREATE TABLE B(
id INT IDENTITY(1,1) NOT NULL,
field1 VARCHAR(10) NULL,
field2 INT NULL
);
INSERT INTO A
(field1,field2)
VALUES
(1,'a'),(2,'b'),(3,'c'),(2,'d'),(5,'e'),
(6,'f'),(7,'g'),(8,'h'),(9,'i'),(2,'j');
INSERT INTO B
(field1,field2)
VALUES
('a',1),('b',2),('c',3),('d',4),('e',5),
('f',6),('g',7),('h',8),('i',9),('j',2),('k',3);
DECLARE @begin INT=0,@end INT=200;
派生テーブル
/*derived tables*/
SELECT
C.id,C.field1,C.field2,C.field3
FROM
(
SELECT
A.id,A.field1,A.field2,B.field2 AS field3,
ROW_NUMBER() OVER (ORDER BY A.id) AS iRow
FROM
A INNER JOIN B ON A.field1=B.id
) C
WHERE iRow BETWEEN @begin AND @end;
一時テーブル
/*temporary tables*/
CREATE TABLE #C (
iRow INT IDENTITY(1,1),
id bigint,
field1 INT,
field2 VARCHAR(50),
field3 INT );
INSERT INTO #C
(id,field1,field2,field3)
SELECT TOP 1000
A.id,A.field1,A.field2,B.field2
FROM
A INNER JOIN B ON A.field1=B.id
ORDER BY
A.id;
SELECT id,field1,field2,field3
FROM #C
WHERE iRow BETWEEN @begin AND @end;
DROP TABLE #C;
@ user16484はすでに パフォーマンスが優れているもの:派生テーブルまたは一時テーブル をコメントで示しています。
また、派生テーブルもカバーする Temp Table 'vs' Table Variable 'vs' CTE。 も参照してください。
簡単な要約:#tempテーブルにはインデックスを作成でき、一意のインデックス/制約を設定でき、同じクエリで複数回参照でき、複数のクエリで参照(FROMまたはJOIN)できます。派生テーブルは、1回のクエリで一度参照(FROMまたはJOIN)できます。
パフォーマンスの観点から、Profiler for SQL:BatchCompletedおよびRPC:Completedを引き出し、読み取り、書き込み、CPU、および期間の列を見て、派生テーブルのいくつかの実行と#tempテーブルとインデックス付き#tempテーブルの違いを確認します。特定の各クエリ。
一般に、これを複数回使用する場合は、#temp tableが優先されます。多数のテーブルを結合する場合は、おそらく#temp tableが優先されます。少数のテーブルのみを結合する場合、派生テーブルが勝つ合理的なチャンスがあります。それをベンチマーク!
一般に、特定のクエリと一時的な結果のサイズによって異なります。
与えられた特定のシナリオ(ページング)では、一時テーブルは完全に不要です。 1000行を一時テーブルに保存して最初の200行を返すのはなぜですか?このシナリオで「派生」テーブルまたはCTEを使用すると、完全な結果セットをどこにも保存する必要がなく、ほとんどの場合生成する必要もないため、はるかに効率的です。たとえば、200行の最初のページを要求する場合、最初の200行のみをベーステーブルから取得する必要があります(既存のインデックスがクエリで要求された並べ替え順序をサポートできる場合)。