テーブル構造と期待される結果のサンプル データが提供されない限り、改善できる点を簡単にいくつか紹介します (これらのいくつかは、上記の他のユーザーによって既に言及されています)。
<オール>はい、ほとんどの場合、SET ベースのアプローチが最速であることに同意しますが、中間結果セットをどこかに保存する必要がある場合は、テーブル変数の代わりに一時テーブルを使用することをお勧めします。一時テーブルは、これら 2 つのオプションの間で「害が少ない」ものです。テーブル変数の使用を避けるべきいくつかの理由を以下に示します:
- SQL Server は、実行計画の構築中にテーブル変数に関する事前の統計を持たないため、実行計画の構築中にテーブル変数から返されるレコードは 1 つだけであると常に見なされます。それに応じて、ストレージ エンジンはクエリの実行に必要なだけの RAM メモリを割り当てます。しかし実際には、テーブル変数が実行中に何百万ものレコードを保持する可能性があります。その場合、SQL Server は実行中にデータをハード ディスクに強制的に書き込むことになり (sys.dm_os_wait_stats に大量の PAGEIOLATCH が表示されます)、クエリが大幅に遅くなります。
- 上記の問題を解決する 1 つの方法は、テーブル値が使用される各クエリの最後にステートメント レベルのヒント OPTION (RECOMPILE) を指定することです。これにより、SQL Server は実行時に毎回これらのクエリの実行プランを作成し、メモリ割り当てが少なくなる問題を回避できます。ただし、これには欠点があります。SQL Server は、そのストアド プロシージャに対して既にキャッシュされている実行プランを利用できなくなり、毎回再コンパイルが必要になり、パフォーマンスがある程度低下します。したがって、基になるテーブルのデータが頻繁に変更されるか、ストアド プロシージャ自体が頻繁に実行されないことがわかっている場合を除き、このアプローチは Microsoft MVP によって推奨されません。