現象
複数の行を含むテーブル変数を作成し、他のテーブルと結合すると、クエリオプティマイザーが効率的でないクエリプランを選択する場合があり、クエリのパフォーマンスが低下する可能性があります。
解決方法
この修正プログラムを適用した後、トレースフラグ2453を有効にして、テーブル変数が、必要な数の行が変更された場合に再コンパイルをトリガーできるようにすることができます。 これにより、クエリオプティマイザーはより効率的なプランを選ぶことができます。 この問題は、次の累積的な更新プログラム、または SQL Server 用の Service Pack で最初に修正されました。
SQL Server 2014 の累積更新プログラム3 /en-us/help/2984923
SQL Server 用の新しい累積更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとすべてのセキュリティ修正が含まれています。 SQL Server の最新の累積的な更新プログラムを確認します。
サービスパックは累積されます。 Service Pack は累積的であり、 最新の Service Pack には新しい修正プログラムと共に、それ以前の Service Pack に含まれていたすべての修正プログラムが含まれています。 このサービスパックの最新の service pack と最新の累積的な更新プログラムを適用することをお勧めします。 最新の service pack をインストールする前に、以前のサービスパックをインストールする必要はありません。 最新の service pack と最新の累積的な更新プログラムの詳細については、次の記事の表1を参照してください。
詳細情報
バッチまたはプロシージャでテーブル変数を使用すると、テーブル変数の最初の空の状態に合わせてクエリがコンパイルされ、最適化されます。 このテーブル変数に実行時に多くの行が設定されている場合、プリコンパイル済みのクエリプランは最適化されなくなる可能性があります。 たとえば、多くの場合、クエリは入れ子になったループで結合されている可能性があります。 このクエリプランは、テーブル変数に何百万もの行が含まれている場合は、効率的ではありません。 ハッシュ結合は、このような条件下で適切な選択肢となる可能性があります。 新しいクエリプランを取得するには、再コンパイルする必要があります。 ただし、他のユーザーテーブルや一時テーブルとは異なり、テーブル変数の行カウントの変更では、クエリ再コンパイルはトリガーされません。 通常、この問題は、独自のオーバーヘッドコストを持つオプション (RECOMPILE) で回避できます。トレースフラグ2453を使用すると、オプション (再コンパイル) を使わずに、クエリの再コンパイルを行うことができます。 このトレースフラグは、2つの主な側面のオプション (RECOMPILE) とは異なります。(1) 他のテーブルと同じ行カウントのしきい値を使用します。 オプション (RECOMPILE) とは異なり、実行するたびにクエリをコンパイルする必要はありません。 行カウントの変更が事前に定義されたしきい値を超えた場合にのみ、再コンパイルがトリガーされます。(2) オプション (再コンパイル) では、クエリがパラメーターをピークし、クエリを最適化します。 このトレースフラグでは、パラメーターのピークは強制されません。注 このトレースフラグは、実行時にオンになっている必要があります。 このトレースフラグは QUERYTRACEON では使用できません。 このトレースフラグは、クエリの再コンパイルの数を増やすことができるため、クエリの最適化を改善することで、コストを節約できるため、注意して使用する必要があります。
状態
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。