Exchange Spill イベント クラス

Exchange Spill イベント クラスは、並列クエリ プランの通信バッファが一時的に tempdb データベースに書き込まれたことを示します。これは、クエリ プランに複数の範囲スキャンがある場合に限り、まれに発生します。

通常、そのような範囲スキャンを生成する Transact-SQL クエリには、多くの BETWEEN 操作が含まれています。各 BETWEEN 操作では、テーブルまたはインデックスから行の範囲を選択します。または、(T.a > 10 AND T.a < 20) OR (T.a > 100 AND T.a < 120) などの式を使用して、複数の範囲を取得できます。さらに、クエリ プランでは、このような範囲を順番にスキャンする必要があります。これは T.a に ORDER BY 句があり、プラン内の反復子で並べ替え順に組を使用することが必要なためです。

このようなクエリのクエリ プランに複数の Parallelism 操作が含まれているときは、Parallelism 操作によって使用されるメモリ通信バッファがいっぱいになり、その結果クエリの実行の進行が停止するという状況が起こります。このような状況では、Parallelism 操作のいずれかにより、入力バッファの行を使用できるように、出力バッファが tempdb に書き込まれます (この操作を Exchange Spill と呼びます)。最終的には、書き込まれた行は、コンシューマでその行を使用する準備が整ったときにコンシューマに返されます。

同じ実行プラン内で複数の Exchange Spill を行うことができますが、これによって非常にまれにクエリの実行速度が低下する場合があります。同じクエリ プランの実行内に 5 つを超える書き込みがある場合は、サポート担当者に問い合わせてください。

Exchange Spill は一時的なもので、データの分布が変更されると解消されることがあります。

Exchange Spill イベントを回避するには、いくつかの方法があります。

  • 結果セットを並べ替える必要がない場合は、ORDER BY 句を省略します。

  • ORDER BY が必要な場合は、複数の範囲スキャンに参加する列 (上記の例の T.a) を ORDER BY 句から削除します。

  • インデックス ヒントを使用して、オプティマイザが当該のテーブルの別のアクセス パスを使用するようにします。

  • 別のクエリ実行プランを生成するようにクエリを書き直します。

  • クエリの末尾またはインデックス操作に MAXDOP = 1 オプションを追加することにより、クエリを連続して実行させます。詳細については、「max degree of parallelism オプション」および「並列インデックス操作の構成」を参照してください。

重要な注意事項重要

クエリ オプティマイザが実行プランを生成するときに Exchange Spill イベントが発生している場所を特定するには、トレースで Showplan イベント クラスも収集する必要があります。ノード ID を返さない Showplan Text イベント クラスと Showplan Text (Unencoded) イベント クラスを除く、任意の Showplan イベント クラスを選択できます。Showplan のノード ID で、クエリ オプティマイザがクエリ実行プランの生成時に実行する各操作が特定されます。これらの操作はオペレータと呼ばれ、Showplan の各オペレータにはノード ID があります。Exchange Spill イベントの ObjectID 列は Showplan のノード ID に対応するので、エラーの原因であるオペレータつまり操作を判別できます。Showplan イベント クラスの詳細については、「SQL Server Profiler のイベント クラスを使用した実行プランの表示」を参照してください。

Exchange Spill イベント クラスのデータ列

データ列名

データ型

説明

列 ID

フィルタの適用

ApplicationName

nvarchar

SQL Server のインスタンスへの接続を作成したクライアント アプリケーションの名前。この列には、プログラムの表示名ではなく、アプリケーションによって渡された値が格納されます。

10

ClientProcessID

int

クライアント アプリケーションが実行されているプロセスに対し、ホスト コンピュータが割り当てた ID。クライアントによりクライアント プロセス ID が指定されると、このデータ列が作成されます。

9

DatabaseID

int

USE database ステートメントで指定されたデータベースの ID。特定のインスタンスについて USE database ステートメントが実行されていない場合は、既定のデータベースの ID となります。SQL Server Profiler では、ServerName データ列がトレースにキャプチャされ、そのサーバーが利用可能な場合、データベースの名前が表示されます。データベースに対応する値は、DB_ID 関数を使用して特定します。

3

DatabaseName

nvarchar

ユーザーのステートメントが実行されているデータベースの名前。

35

EventClass

int

イベントの種類 = 127。

27

不可

EventSequence

int

要求内の特定のイベントのシーケンス。

51

不可

EventSubClass

int

イベント サブクラスの種類。

1 = 書き込み開始

2 = 書き込み終了

21

GroupID

int

SQL トレース イベントが発生したワークロード グループの ID。

66

HostName

nvarchar

クライアントが実行されているコンピュータの名前。クライアントによりホスト名が指定されている場合は、このデータ列に値が格納されます。ホスト名を指定するには、HOST_NAME 関数を使用します。

8

IsSystem

int

イベントがシステム プロセスで発生したか、ユーザー プロセスで発生したかを示します。1 = システム、0 = ユーザーです。

60

LoginName

nvarchar

ユーザーのログイン名 (SQL Server セキュリティ ログインまたは <DOMAIN>\<username> という形式の Windows ログイン資格情報)。

11

LoginSid

image

ログイン ユーザーのセキュリティ ID 番号 (SID)。この情報は、master データベースの syslogins テーブルにあります。各 SID はサーバー上の各ログインに固有です。

41

NTDomainName

nvarchar

ユーザーが所属する Windows ドメイン。

7

NTUserName

nvarchar

Windows のユーザー名。

6

ObjectID

int

オブジェクトに対してシステムが割り当てた ID。Showplan のノード 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