SQL Server のバッチまたはタスクのスケジュール設定

SQL Server の各インスタンスは、個別のオペレーティング システム プロセスです。各インスタンスで処理するユーザーからの同時実行要求は、数千に上る場合もあります。SQL Server インスタンスではそのような同時実行タスクを効率的に管理するために、Microsoft Windows スレッド、またはファイバが構成されている場合はファイバが使用されます。各 SQL Server インスタンスはシステム プロセスに対し複数のスレッドを常に実行します。実行されるスレッドには、サーバーの Net-Library ごとに 1 つ以上のスレッド、ネットワーク I/O を処理するネットワーク スレッド、サービス コントロール マネージャと通信するシグナル スレッドなどがあります。

スケジュールについて

SQL Server の各インスタンスには、オペレーティング システムに似た環境を実装する内部層があります。Windows カーネルを呼び出さずに、同時実行タスクのスケジュール設定や同期を行うために、この内部層が使用されます。また、この内部層ではファイバまたは Windows スレッドのスケジュールを効果的に設定することもできます。各 SQL Server インスタンスでは、ユーザーからのクエリを処理する Windows スレッドまたはファイバのプールが管理されます。このプールの最大サイズは、max worker threads サーバー構成オプションで制御します。

要求またはタスクの処理方法を理解するうえで、次の基本的な用語を理解しておくことが役立ちます。

  • 接続
    ユーザーが正常にログインすると、接続が確立されます。接続の確立後は、1 つ以上の Transact-SQL ステートメントを送信して実行できます。ユーザーが明示的にログアウトするか接続が終了すると、接続が閉じられます。

  • バッチ
    SQL バッチとは、クライアントから SQL Server インスタンスに、実行用に送信された 1 つ以上の Transact-SQL ステートメントの集まりです。バッチは、ユーザーがデータベース エンジンに送信する作業の単位を表します。

  • タスク
    タスクとは、SQL Server によりスケジュールが設定された作業の単位を表します。1 つのバッチを 1 つ以上のタスクにマップできます。たとえば、並列クエリは複数のタスクで実行されます。

  • Windows スレッド
    Windows スレッドは独立した実行メカニズムを表します。

  • ファイバ
    ファイバとは、Windows スレッドよりもリソース消費が少なく、ユーザー モードでのコンテキストの切り替えが可能な簡易スレッドです。1 つの Windows スレッドを多数のファイバにマップできます。

  • ワーカー スレッド
    ワーカー スレッドとは SQL Server の論理的なスレッドを表し、内部的には Windows スレッドまたは (簡易プーリングが ON になっている場合は) ファイバのいずれかと一対一にマップされます。メモリが不足するか、ワーカー スレッドが長時間アイドル状態になることでワーカー スレッドの割り当てが解除されるまで、このマッピングは保持されます。タスクとワーカー スレッドの関連付けは、タスクが終了するまで保持されます。

ユーザー接続とワーカー スレッド リソースの管理

スレッドとファイバは、使用するリソースが少ないとはいえ、リソースを消費することに変わりありません。ユーザー接続が数百も数千もあるシステムの場合、接続ごとに 1 つのワーカー スレッドを設けると、大量のリソースが消費され SQL Server の効率が低下することがあります。また、実際には大部分の接続は、クライアントからのバッチの受信待ちに大半の時間が費やされます。このため、ユーザー接続ごとに専用のワーカーを割り当てる必要はありません。代わりに、SQL Server インスタンスによってワーカー スレッドのプールが使用されます。ワーカー スレッドのプールは、そのインスタンスで同時にバッチを実行しているユーザー接続の数に見合った大きさがあれば十分です。SQL Server インスタンスの max worker threads オプションを既定値 0 にしておくと、ユーザー接続が複数のワーカー スレッドに効率的にマップされます。その結果、リソースが無駄に消費されなくなります。

ファイバを使用するための SQL Server の構成

サーバー構成オプション lightweight pooling は、SQL Server インスタンスが Windows スレッドとファイバのどちらを使用するかを制御します。このオプションの既定値は 0 です。このとき、SQL Server インスタンスは、max worker threads オプションで設定した値を最大とする数の Windows スレッドを各ワーカー スレッドにスケジュールします。lightweight pooling を 1 に設定すると、SQL Server は Windows スレッドではなくファイバを使用します。この状態をファイバ モードでの実行と呼びます。ファイバ モードでは SQL Server インスタンスにより、SQL スケジューラ単位に Windows スレッドが 1 つ割り当てられ、max worker threads オプションで設定した値になるまで、ワーカー スレッド単位にファイバが 1 つずつ割り当てられます。Windows スレッドとファイバのどちらを使用する場合でも、SQL Server インスタンスでは同一のアルゴリズムでタスクのスケジュールの設定および同期が行われます。SQL Server Express ではファイバがサポートされません。詳細については、「lightweight pooling オプションの使用」を参照してください。ルーチン処理にファイバ モード スケジューリングを使用することはお勧めしません。これは、コンテキストの切り替えがもたらす本来の利点が損なわれることでパフォーマンスが低下する場合があること、および、ファイバ モードでは SQL Server の一部のコンポーネントが正常に機能しない場合があるためです。詳細については、「簡易プーリング」を参照してください。

バッチまたはタスクのスケジュール設定の動作

データベース エンジンに接続したアプリケーションには、SPID (セッション ID) が割り当てられます。SPID に関連付けられた内部データ構造により、接続を閉じるまで保存しておく必要があるすべての情報が管理されます。SQL Server インスタンスがクライアントからバッチを受信すると、バッチは 1 つ以上のタスクに分解され、ワーカー スレッドのプールにある使用可能なワーカー スレッドにそれぞれのタスクが関連付けられます。ワーカー スレッドは、タスクが終了するまでそのタスクにバインドされます。ワーカー スレッドでは、関連する SQL スケジューラの要求を実行します。max worker threads 値に達する前に空いているワーカー スレッドがなくなると、SQL Server インスタンスにより新しいバッチ用に新しいワーカー スレッドが割り当てられます。使用可能な空きスレッドまたはファイバがなく、max worker threads 値に既に達している場合、ワーカー スレッドが解放されるまでは SQL Server インスタンスによって新しいタスクがブロックされます。

ワーカーをタスクと関連付けると、関連付けはタスクが完了する (たとえば、バッチで生成した最後の結果セットをクライアントに返す) まで保持されます。タスクが完了した時点でワーカー スレッドは解放され、次のバッチに関連付けられたタスクと関連付けることができます。

ある接続での作業がデータベース エンジンによってアクティブに処理されるのは、バッチを受信してから結果をクライアントに返すまでの間のみです。この間、アクティブな処理を必要としない時間もあります。たとえば、データベース エンジンが読み取り操作により現在のクエリに必要なデータが取得されるのを待機したり、別のバッチによるロックが解放されるのを待機している時間です。タスクとワーカーの関連付けは、あるリソースでタスクがブロックされている間も保持されます。

バッチに関連付けられたタスクがデータベース エンジンにより開始されるときは、必ず、タスクに関連付けられたワーカー スレッドが作業を実行するためにスケジュールが設定されます。ワーカー スレッドがタスクの作業を完了すると、そのワーカー スレッドは SQL Server インスタンスによって、準備が整っている次のタスクにディスパッチされます。SPID は接続が終了するまで変わりません。接続が長期にわたる場合、個々のバッチ タスクを多数のワーカー スレッドに分散して実行することもあります。たとえば、最初のバッチのタスクが worker1 で実行され、2 番目のバッチのタスクが worker2 で実行されることがあります。複数のステートメントを並列に処理することもできます。その場合、バッチが複数のタスクに分割され、タスクは複数のワーカー スレッドで同時に実行されます。