通知の計画

クエリ通知を効果的に使用するには、アプリケーションにはクエリ通知によるメリットがあるかどうか、アプリケーションが使用するクエリが通知をサポートしているかどうか、アプリケーションはどのように通知のサブスクライブや受信を行うかを検討する必要があります。

クエリ通知は、クエリのデータの変更頻度が比較的少ない場合、データが変更されてもアプリケーションですぐにデータを更新する必要がない場合、またはクエリが「クエリ通知の作成」で説明されている要件や制限を満たしている場合に、データベースとアプリケーション間のやり取りを削減することができます。Web ベースのアプリケーションの多くは、この条件を満たしています。このようなアプリケーションでは、クエリ通知を利用できます。

クエリ通知は、すべてのシナリオにメリットがあるとは限りません。クエリ通知は、アプリケーションがデータベースのデータを頻繁に読み取ったとしても、データの更新頻度が比較的少ない状況で役に立ちます。たとえば、オンライン カタログ アプリケーションは、読み取られる頻度の方が、カタログが更新される頻度よりも高くなります。一方、オンライン ショッピング カートでは、特定のコンテンツがきわめて頻繁に更新されるので、クエリ通知によるメリットは少なくなります。

クエリ通知は、アプリケーションが共通の構造を持ち、パラメーター値のみが異なるクエリを実行する場合に、効果が高くなります。次に例を示します。

SELECT ProductNumber, Name FROM Production.Product WHERE ListPrice < 300
SELECT ProductNumber, Name FROM Production.Product WHERE ListPrice < 500

この場合、どちらの通知に対するクエリ通知のサブスクリプションでも、同じ内部テンプレートが使われるので、クエリ構造の異なる 2 種類のクエリの通知を要求する場合に比べて、SQL Server のオーバーヘッドが小さくなります。ただし、クエリのパラメーターは保持されることに注意してください。クエリは同じテンプレートを使用していてますが、ListPrice が 350 のアイテムを追加した場合、2 番目のクエリは通知を生成しますが、最初のクエリは通知を生成しません。

テーブルでクエリ通知がアクティブな場合、テーブルの更新にはより多くのリソースが使用されます。データベース エンジンが、サブスクリプションを確認し、必要に応じて通知を生成するという余分な作業を行うことになるためです。内部テンプレートを再利用すると、1 サブスクリプションあたりのオーバーヘッドを最小限に抑えることができます。したがって、同様の構造を持つクエリを送信するアプリケーションでのみ、クエリ通知を使用することをお勧めします。構造の異なるクエリを送信するアプリケーションでは、クエリ通知を使用しないことをお勧めします。

たとえば、特定の価格帯のカタログ アイテムを表示するアプリケーションは、同じ構造のクエリを送信します。この場合、データベース エンジンは、各クエリに同じ内部テンプレートを再利用できるので、クエリ通知を使用することでパフォーマンスが向上する可能性があります。一方、アドホック レポートを許可するアプリケーションは、構造の異なるクエリを送信します。この場合は、アプリケーションでクエリ通知を使用しないようにします。

データベース エンジンは、登録済みのサブスクリプションの 1 つでも内部テンプレートが使用される限り、その内部テンプレートを保持します。データベース エンジンは、ある特定のテーブルで使用できる内部テンプレートの種類の数が制限されます。この制限に達すると、データベース エンジンは新たにテンプレートが作成される原因となり得るサブスクリプションを登録しなくなります。代わりに、データベース エンジンは、サブスクリプションを登録できなかったことを示すサブスクリプション メッセージを直ちに生成します。

効率的なクエリ通知方法の計画

一般に、クエリ通知が適切に機能するのは、通知の総数が比較的少なく、データの変更時にアプリケーションが即座に通知を受ける必要がない場合です。このモデルに一致するのが標準的な Web 層キャッシュ無効化シナリオであり、クエリ通知を使用するのに適していると考えられます。瞬時に通知を受け取る必要がある場合、ネットワーク インフラストラクチャが低速で信頼性に欠ける場合、または通知が大量にある場合には、クエリ通知はアプリケーションにとって最適な選択肢とは言えません。

クエリ通知を使用する場合は、クエリ通知を実際に使用する環境と規模でアプリケーションをテストし、調整します。負荷が最も大きいと予想される現実的なユースケース シナリオを検討し、アクティビティの突発的な急増に備えた計画を立てます。

信頼性のある 1 秒未満のクエリ通知を必要とする状況でクエリ通知を使用する場合は、高パフォーマンスの OLTP アプリケーションを構築する際に適用する手法と同じ手法をクエリ通知アプリケーションに適用します。

  • アプリケーションがロックを保持する時間が 1 秒未満であることを確認します。たとえば、パフォーマンスの信頼性が低いネットワーク上のクライアントから、複数のステートメントを含むトランザクションを実行しないようにします。

  • ユーザー データ テーブルのホットスポットを特定し、排除します。

  • クエリ通知が設定された関連するユーザー テーブルが更新されるたびに、内部クエリ通知テーブルが順次スキャンされることがよくあります。内部クエリ通知テーブルで保持されるテーブル レベルのロックがボトルネックになる可能性がある場合は、クエリ通知が設定されたユーザー テーブルを複数のテーブルにパーティション分割して、データが変更されるたびに評価する必要がある使用可能な通知の数を減らすことを検討します。

通知要求の有効期間が短い場合は、SqlDependency コンストラクターで既定の 5 日よりも大幅に短いタイムアウト (1 分など) を使用することを検討します。これにより、内部クエリ通知テーブルの行数を大幅に減らすことができます。その結果、これらのテーブルの処理に要する時間が短縮され、テーブルでのロック競合を減らすことができます。

クエリ通知に代わる方法

データの更新頻度が高く、未処理の通知要求が多数発生する環境で、データ変更に関する通知に対応する時間を迅速に予測できる必要がある場合は、次のような代替ソリューションを検討します。

  • 監視対象のテーブルで AFTER UPDATE トリガーを作成し、SQL Server Service Broker を使用して、通知を必要とするエンティティにメッセージを送信するトリガー動作を設定します (これはさまざまな方法で設計できます。たとえば、変更を通知する必要があるエンティティを示す列を対象のテーブルに追加する方法や、通知を必要とするエンティティに関する情報を格納する別のテーブルに主テーブルを結合する方法があります)。

  • クエリ通知に依存しないカスタムのアプリケーション層ソリューションを使用します。たとえば、監視対象のデータをメイン メモリ オブジェクトのコレクションに保持するミドルウェア アプリケーションから発生するように通知を構成します。通知の条件を満たす方法でオブジェクトが変更されたときに、アプリケーションで通知を生成できます。

  • メモリ内オブジェクト キャッシュとオブジェクトに登録したコールバック関数に基づいて、変更通知機構をサポートする Windows Server AppFabric キャッシュを使用します。

関連項目

概念