一時テーブル(#tmp)とテーブル変数(@tmp)にはいくつかの違いがありますが、以下のMSDNリンクで説明されているように、tempdbの使用はそれらの1つではありません。
経験則として、少量から中量のデータと単純な使用シナリオでは、テーブル変数を使用する必要があります。 (これは非常に幅広いガイドラインですが、もちろん多くの例外があります。以下および以下の記事を参照してください。)
それらから選択する際に考慮すべきいくつかのポイント:
-
一時テーブルは実際のテーブルであるため、CREATE INDEXなどを実行できます。インデックスによるアクセスが高速になる大量のデータがある場合は、一時テーブルが適しています。
-
テーブル変数は、PRIMARYKEYまたはUNIQUE制約を使用してインデックスを持つことができます。 (一意でないインデックスが必要な場合は、一意の制約の最後の列として主キー列を含めるだけです。一意の列がない場合は、ID列を使用できます。)SQL2014にも一意でないインデックスがあります。 。
-
テーブル変数はトランザクションと
SELECT
に参加しません sは暗黙的にNOLOCK
を使用します 。トランザクションの動作は非常に役立ちます。たとえば、プロシージャの途中でロールバックする場合、そのトランザクション中に入力されたテーブル変数は引き続き入力されます! -
一時テーブルでは、おそらく頻繁にストアドプロシージャが再コンパイルされる可能性があります。テーブル変数はそうではありません。
-
SELECT INTOを使用して一時テーブルを作成できます。これは、作成が速く(アドホッククエリに適しています)、一時テーブルの構造を事前に定義する必要がないため、時間の経過とともに変化するデータ型に対処できる場合があります。
-
関数からテーブル変数を返すことができるため、ロジックをカプセル化して再利用するのがはるかに簡単になります(たとえば、関数を任意の区切り文字で値のテーブルに分割する関数を作成できます)。
-
ユーザー定義関数内でテーブル変数を使用すると、それらの関数をより広く使用できるようになります(詳細については、CREATE FUNCTIONのドキュメントを参照してください)。関数を作成している場合は、特に必要がない限り、一時テーブルではなくテーブル変数を使用する必要があります。
-
テーブル変数と一時テーブルの両方がtempdbに格納されます。ただし、テーブル変数(2005以降)は、デフォルトで現在のデータベースの照合と、tempdb(ref)のデフォルトの照合を使用する一時テーブルの照合になります。つまり、一時テーブルを使用していて、db照合がtempdbのものと異なる場合は照合の問題に注意する必要があり、一時テーブルのデータをデータベースのデータと比較する場合は問題が発生します。
-
グローバル一時テーブル(## tmp)は、すべてのセッションとユーザーが使用できる別のタイプの一時テーブルです。
さらに読む:
-
dba.stackexchange.comでのMartinSmithのすばらしい答え
-
2つの違いに関するMSDNFAQ:https://support.microsoft.com/en-gb/kb/305977
-
MDSNブログ記事:https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-temporary-table
-
記事:https://searchsqlserver.techtarget.com/tip/Temporary-tables-in-SQL-Server-vs-table-variables
-
一時テーブルと一時変数の予期しない動作とパフォーマンスへの影響:SQLblog.comのPaul White