SQL Serverで複雑なクエリを作成していると、CTE(共通テーブル式)、一時テーブル、テーブル変数のどれを使うべきか迷うことがあります。どれも一時的なデータ処理に利用できますが、保存期間、性能、トランザクション、データ量への適性などに違いがあります。この記事では、それぞれの特徴を比較し、どのような状況で使い分けるべきかを実例を交えて解説します。
CTE・一時テーブル・テーブル変数の基本的な違い
SQL Serverでは、処理途中のデータを一時的に扱う方法として、CTE、一時テーブル、テーブル変数がよく利用されます。
しかし、それぞれの仕組みは大きく異なります。CTEはクエリ内で定義する一時的な結果セットであり、一時テーブルやテーブル変数は実際にデータを保持する領域を作成します。
| 種類 | 特徴 |
|---|---|
| CTE | 1つのSQL文内で利用する一時的な結果 |
| 一時テーブル(#table) | tempdbに作成される一時テーブル |
| テーブル変数(@table) | 変数として扱う小規模データ向けのテーブル |
どれを選ぶかは、処理するデータ量や処理の複雑さによって判断することが重要です。
CTEが適しているケース
CTEは、SQL文を読みやすく整理したい場合や、再帰処理を行いたい場合に適しています。
例えば、複数のサブクエリが入れ子になっているSQLでは、CTEを利用することで処理内容を段階的に記述できます。
WITH SalesSummary AS (
SELECT CustomerId, SUM(Amount) AS TotalAmount
FROM Sales
GROUP BY CustomerId
)
SELECT * FROM SalesSummary;
このように、一度計算結果に名前を付けることで、複雑なSQLでも理解しやすくなります。
また、社員の階層構造やフォルダ構造など、親子関係を持つデータを処理する場合には再帰CTEが有効です。
一時テーブルが適しているケース
一時テーブルは、大量のデータを途中結果として保持したい場合に適しています。
作成した一時テーブルはtempdbに保存され、複数のSQL文から参照できます。そのため、複雑な処理を複数段階に分けたい場合に便利です。
例えば、大量の売上データを集計して、その結果をさらに分析するような処理では、一時テーブルを利用すると効率的になる場合があります。
CREATE TABLE #SalesTemp(
CustomerId INT,
TotalAmount DECIMAL(10,2)
);
一時テーブルにはインデックスを作成できるため、大量データを扱う処理では性能改善につながることがあります。
例えば数百万件のデータを一度集計し、その結果を何度も検索する処理では、一時テーブルの方がCTEより適しているケースがあります。
テーブル変数が適しているケース
テーブル変数は、小規模なデータを一時的に保持する場合に向いています。
例えば、数件から数百件程度の処理結果を保持して、ストアドプロシージャ内で利用するような場面で便利です。
DECLARE @UserList TABLE(
UserId INT,
UserName NVARCHAR(50)
);
テーブル変数はスコープが限定されており、宣言したバッチやストアドプロシージャ内でのみ利用できます。
ただし、大量データを格納する用途では注意が必要です。SQL Serverのバージョンや設定によって改善されていますが、統計情報が不足することで最適な実行計画が選択されない場合があります。
性能面で比較するときのポイント
CTE、一時テーブル、テーブル変数は単純にどれが高速というものではなく、処理内容によって結果が変わります。
| 項目 | CTE | 一時テーブル | テーブル変数 |
|---|---|---|---|
| 大量データ | 不向きな場合あり | 向いている | 不向き |
| 複数回参照 | 再計算される場合あり | 向いている | 可能 |
| インデックス | 不可 | 作成可能 | 制限あり |
| SQLの可読性 | 高い | 普通 | 普通 |
例えば、同じ計算結果を何度も利用する場合、CTEでは毎回評価される可能性があります。その場合は、一時テーブルへ保存した方が効率的になることがあります。
反対に、単純な一回限りの集計処理であればCTEの方がSQLを簡潔にできます。
ストアドプロシージャでの使い分け例
実際の業務システムでは、処理内容によって以下のように使い分けると管理しやすくなります。
- 複雑なSELECT文を整理したい場合:CTE
- 大量データを加工して複数ステップで利用する場合:一時テーブル
- 少量の一時データを処理する場合:テーブル変数
例えば、月次売上レポートを作成する場合、数百万件の注文データを集計するなら一時テーブルを利用し、単純なランキング計算ならCTEを利用するといった判断になります。
選択時に注意すべきポイント
CTE、一時テーブル、テーブル変数を選択するときは、現在のデータ量だけではなく、将来的な増加も考慮する必要があります。
開発初期では数百件しかないデータでも、数年後には数百万件になる可能性があります。その場合、最初はテーブル変数で問題なくても、後から性能問題になることがあります。
また、実際のシステムでは実行計画を確認し、処理時間やI/O負荷を測定して判断することが重要です。
まとめ:用途とデータ量でCTE・一時テーブル・テーブル変数を選ぶ
SQL ServerのCTE、一時テーブル、テーブル変数は、それぞれ得意な用途が異なります。
SQLを整理したい場合や再帰処理にはCTE、大量データの加工や複数回利用には一時テーブル、小規模な一時処理にはテーブル変数が適しています。
重要なのは、単純なルールで決めるのではなく、データ量、処理回数、性能要件を考慮して選択することです。適切に使い分けることで、SQL Serverの処理性能と保守性を両立できます。


コメント