Exchange Spill イベント クラスは、並列クエリ プランの通信バッファーが tempdb データベースに一時的に書き込まれたことを示します。 これは、クエリ プランに複数の範囲スキャンがある場合にのみ、まれに発生します。
通常、このような範囲スキャンを生成する Transact-SQL クエリには多くの BETWEEN 演算子があり、各演算子はテーブルまたはインデックスから行の範囲を選択します。 または、(T.a > 10 AND T.a < 20) や (T.a > 100 AND T.a < 120) などの式を使用して複数の範囲を取得することもできます。 さらに、クエリ プランでは、T.a に ORDER BY 句があるため、またはプラン内の反復子でタプルを並べ替えられた順序で使用する必要があるため、これらの範囲を順番にスキャンする必要があります。
このようなクエリのクエリ プランに複数の Parallelism 演算子がある場合、 Parallelism 演算子によって使用されるメモリ通信バッファーがいっぱいになり、クエリの実行の進行状況が停止する状況が発生する可能性があります。 このような状況では、 並列処理 演算子の 1 つは、一部の入力バッファーの行を使用できるように、出力バッファーを tempdb ( 交換スピルと呼ばれる操作) に書き込みます。 最終的に、コンシューマーがそれを処理する準備ができたら、スピルされた行がコンシューマーに返されます。
非常にまれに、同じ実行プラン内で複数の交換スピルが発生し、クエリの実行速度が低下する可能性があります。 同じクエリ プランの実行内で 5 つ以上のスピルが発生した場合は、サポート担当者にお問い合わせください。
Exchange の流出は一時的なものであり、データ分散の変化に応じて消えることがあります。
交換スピルイベントを回避する方法は複数あります。
結果セットを順序付けする必要がない場合は、ORDER BY 句を省略します。
ORDER BY が必要な場合は、ORDER BY 句から複数範囲スキャン (上の例では T.a) に参加する列を削除します。
インデックス ヒントを使用して、オプティマイザーが対象のテーブルで別のアクセス パスを使用するように強制します。
クエリを書き直して、別のクエリ実行プランを生成します。
クエリまたはインデックス操作の最後に MAXDOP = 1 オプションを追加して、クエリのシリアル実行を強制します。 詳細については、「 並列処理の最大限度サーバー構成オプションの構成 」および 「並列インデックス操作の構成」を参照してください。
重要
クエリ オプティマイザーが実行プランを生成するときに Exchange Spill イベントが発生している場所を特定するには、トレースで Showplan イベント クラスも収集する必要があります。 Showplan Text イベント クラスと Showplan Text(Unencoded) イベント クラスを除き、ノード ID を返さない Showplan イベント クラスを選択できます。 Showplans のノード ID は、クエリ オプティマイザーがクエリ実行プランを生成するときに実行する各操作を識別します。 これらの操作は演算子と呼ばれ、Showplan の各演算子にはノード ID があります。 Exchange Spill イベントの ObjectID 列は Showplans のノード ID に対応しているため、エラーの原因となっている演算子 (操作) を特定できます。
Exchange Spill イベント クラスのデータ列
| データ列名 | データの種類 | 説明 | 列 ID | フィルターの適用 |
|---|---|---|---|---|
| ApplicationName | nvarchar | SQL Server のインスタンスへの接続を作成したクライアント アプリケーションの名前。 この列には、プログラムの表示名ではなく、アプリケーションによって渡された値が格納されます。 | 10 | イエス |
| ClientProcessID | int | クライアント アプリケーションが実行されているプロセスに対し、ホスト コンピューターが割り当てた ID。 クライアントによりクライアント プロセス ID が指定されると、このデータ列に値が格納されます。 | 9 | イエス |
| DatabaseID | int | USE database ステートメントで指定されたデータベースの ID、または特定のインスタンスについて USE database ステートメントが実行されていない場合は既定の database となります。 SQL Server Profiler では、 ServerName データ列がトレースにキャプチャされ、そのサーバーが利用可能な場合、データベースの名前が表示されます。 データベースに対応する値は、DB_ID 関数を使用して特定します。 | 3 | イエス |
| DatabaseName | nvarchar | ユーザーのステートメントが実行されているデータベースの名前。 | 35 | イエス |
| EventClass | int | イベントの種類 = 127。 | 二十七 | いいえ |
| EventSequence | int | 要求内の特定のイベントのシーケンス。 | 51 | いいえ |
| EventSubClass | int | イベント サブクラスの種類。 1 = スピルの開始 2 = 液漏れ終了 |
21 (二十一) | イエス |
| GroupID を する | int | SQL トレース イベントが発生したワークロード グループの ID。 | 66 | イエス |
| HostName | nvarchar | クライアントが実行されているコンピューターの名前。 このデータ列にはクライアントからホスト名が提供されている場合に値が格納されます。 ホスト名を指定するには、 HOST_NAME 関数を使用します。 | 8 | イエス |
| IsSystem | int | イベントがシステム プロセスとユーザー プロセスのどちらで発生したか。 1 はシステム、0 はユーザーです。 | 六十 | イエス |
| LoginName | nvarchar | ユーザーのログイン名 (SQL Server セキュリティ ログインまたは Windows ログイン資格情報 ( <DOMAIN>\<username> の形式)。 | 11 | イエス |
| LoginSid | 画像 | ログイン ユーザーのセキュリティ ID 番号 (SID)。 この情報は、master データベースの syslogins テーブルにあります。 各 SID はサーバーのログインごとに一意です。 | 41 | イエス |
| NTDomainName | nvarchar | ユーザーが所属する Windows ドメイン。 | 7 | イエス |
| NTUserName | nvarchar | Windows のユーザー名。 | 6 | イエス |
| ObjectID | int | システムによって割り当てられたオブジェクト ID。 プラン表示のノード ID に対応します。 | 22 | イエス |
| RequestID | int | ステートメントが含まれている要求の ID。 | 49 | イエス |
| ServerName | nvarchar | トレース対象の SQL Server のインスタンスの名前。 | 26 | いいえ |
| SessionLoginName | nvarchar | セッションを開始したユーザーのログイン名。 たとえば、Login1 を使用して SQL Server に接続し、ステートメントを Login2 として実行すると、 SessionLoginName は Login1 と表示され、 LoginName は Login2 を示します。 この列には、SQL Server ログインと Windows ログインの両方が表示されます。 | 64 | イエス |
| SPID | int | イベントが発生したセッションの ID。 | 12 | イエス |
| StartTime | datetime | イベントの開始時刻 (取得できた場合)。 | 14 | イエス |
| TransactionID | bigint | システムによって割り当てられたトランザクション ID。 | 4 | イエス |
| XactSequence | bigint | 現在のトランザクションを説明するトークン。 | 50 | イエス |
こちらもご覧ください
sp_trace_setevent (Transact-SQL) イベント設定関数
インデックス オプションの設定
ALTER INDEX (Transact-SQL)