マージ レプリケーションによるフィルタ選択されたパブリケーションのパーティションの評価方法

パラメータ化されたフィルタおよび結合フィルタを使用してマージ パブリケーションの 1 つ以上のテーブルがフィルタ選択された場合、パブリッシュされたテーブル内のデータはパーティション分割されます。パーティションとは、単にテーブル内の行のサブセットのことです。サブスクライバがパブリッシャと同期する場合、パブリッシャは、サブスクライバがシステム関数 SUSER_SNAME() および HOST_NAME() に対して提供した値を基に、どの行がサブスクライバのパーティションに属しているかを判断する必要があります。フィルタ選択されたデータセットを受け取る各サブスクライバに対して、パブリッシャの変更内容のパーティション メンバシップを決定する処理をパーティション評価と呼びます。

パブリッシュされたテーブルのデータ、およびパラメータ化されたフィルタや関連する結合フィルタの作成時に選択した設定によって、パブリッシュされたテーブルの各行は、次のいずれかになります。

  • 1 つのパーティションに属し、1 つのサブスクライバにのみレプリケートされる (sp_addmergearticle パラメータ @partition_options の値が 3)。たとえば、AdventureWorks2008R2 データベースでは、Employee テーブルをフィルタ句 WHERE Employee.LoginID = SUSER_SNAME() でフィルタ選択できます。各ログイン ID に一致する行が 1 つのサブスクライバにのみ送信されます。

  • 1 つのパーティションに属し、1 つ以上のサブスクライバにレプリケートされる (@partition_options の値が 2)。たとえば、AdventureWorks2008R2 データベースでは、Products テーブルをフィルタ句 WHERE Products.ProductLine = HOST_NAME() でフィルタ選択できます。マウンテン バイクの販売員のグループが、ProductLine 列の値が "M" のすべての行を受け取るように HOST_NAME() 値が上書きされます。値が "M" の各行は 1 つのパーティションにのみ属しますが、複数のサブスクライバに送信されます。HOST_NAME() の使用法の詳細については、「パラメーター化された行フィルター」の「HOST_NAME() によるフィルタ選択」を参照してください。

  • 複数のパーティションに属し、複数のサブスクライバにレプリケートされる (@partition_options の値が 0 または 1)。たとえば、AdventureWorks2008R2 データベースでは、Products テーブルをフィルタ句 WHERE Products.ProductLine = HOST_NAME() or Products.ListPrice < 100 でフィルタ選択できます。この場合、マウンテン バイクの販売員は、販売価格が 100 ドル未満であれば、他のカテゴリに属する製品も販売できます。フィルタ句に OR が指定されているため、この行は複数のパーティションに属する可能性があります。

パーティションの評価方法

パーティションの評価は、事前計算済みパーティション機能が使用されているかどうかによって、マージ レプリケーションの 2 とおりの方法のうち、どちらかで発生します。多くの要件が満たされている場合、既定では、新規のマージ パブリケーションは事前計算済みパーティションを使用して作成され、既存のパブリケーションもこの機能を使用するように自動的にアップグレードされます。すべての要件の一覧については、「事前計算済みパーティションによるパラメータ化されたフィルタのパフォーマンス最適化」を参照してください。

事前計算済みパーティションを使用したパーティションの評価

事前計算済みパーティションを使用した場合、パブリッシャのすべての変更に対するパーティション メンバシップは事前に計算され、パブリッシュされたテーブルに変更が加えられる時点まで保持されます。その結果、サブスクライバはパブリッシャとの同期時に、パーティションに関連する変更内容のダウンロードを即座に開始できます。パーティションの評価処理が実行されることはありません。パブリケーションに変更点、サブスクライバ、およびアーティクルが多数存在する場合は、この機能によってパフォーマンスの大幅な向上が期待できます。

事前計算済みパーティションの評価に関係するシステム テーブルを次に示します。

  • MSmerge_partition_groups

  • MSmerge_current_partition_mappings

  • MSmerge_past_partition_mappings

MSmerge_partition_groups には、パブリケーションで定義されたパーティションごとに 1 行のデータが格納されます。パーティションは次のいずれかで定義または作成されます。

  • sp_addmergepartition または [パブリケーションのプロパティ] ダイアログ ボックスの [データ パーティション] ページを使用して明示的に定義

  • まだ MSmerge_partition_groups にエントリのないパーティションがサブスクライバに必要な場合、サブスクライバの同期時に自動的に作成

他の 2 つのテーブル (MSmerge_current_partition_mappingsMSmerge_past_partition_mappings) は、パブリッシュされたテーブルが変更されると設定されます。パブリケーション データベースのパブリッシュされたテーブルが変更されるたびに、マージ トリガが起動されてメタデータが記録されます。

  • MSmerge_current_partition_mappings には、MSmerge_contents の行と MSmerge_partition_groups の行の一意の組み合わせごとに 1 行のデータが格納されます。たとえば、あるユーザー テーブルの行が 2 つのパーティションに属していて、その行が更新された場合、その更新を反映する 1 行が MSmerge_contents に挿入され、2 行が MSmerge_current_partition_mappings に挿入されます。これは、更新された行が 2 つのパーティションに属していることを示します。

  • MSmerge_past_partition_mappings には、特定のパーティションに属さなくなった行ごとに 1 行のデータが格納されます。行は、以下の場合にパーティションから移動されます。

    • 行が削除された場合。行がユーザー テーブルから削除された場合、MSmerge_tombstone に 1 行が挿入され、MSmerge_past_partition_mappings に 1 つ以上の行が挿入されます。

    • フィルタ選択に使用する列の値が変更された場合。たとえば、パラメータ化されたフィルタが企業の本社のある州に基づいていて、本社が移転した場合、その企業の行 (および他のテーブルの関連する行) は、1 人の販売員のデータ パーティションから別の販売員のパーティションに移動します。既にパーティションに属していないなど、行が更新されている場合は、MSmerge_contents に 1 行が挿入または更新され、1 つ以上の行が MSmerge_past_partition_mappings に挿入されます。

    注意

    パーティションあたり 1 つのサブスクリプションがある重複しないパーティション (sp_addmergearticle@partition_options パラメータの値が 3) を使用した場合、各行は 1 つのパーティションにのみ属し、1 つのサブスクライバでのみ変更されるため、システム テーブル MSmerge_current_partition_mappingsMSmerge_past_partition_mappings は行のパーティション マッピングの追跡には使用されません。

SetupBelongs 処理を使用したパーティションの評価

事前計算済みパーティションを使用しない場合、SetupBelongs 処理が使用されます。同期中に、前回特定のサブスクライバに対してマージ エージェントが実行された後で、パブリッシャ側のフィルタ選択済みテーブルで行われた各変更に対して、パーティションの評価が実行されます。この処理は、パブリッシャと同期するすべてのサブスクライバに対して繰り返し実行されます。

サブスクライバのパーティション評価を実行するため、マージ エージェントはシステム ストアド プロシージャ sp_MSsetupbelongs を呼び出します。このシステム ストアド プロシージャの機能は次のとおりです。

  1. フィルタ選択された各アーティクルに 2 つの一時テーブル #belongs_<RandomNumber>#notbelongs_<RandomNumber> を作成します。

  2. サブスクライバ側で、SUSER_SNAME() 関数および HOST_NAME() 関数によって返された値を使用して、システム ビューのクエリを実行します。このクエリを使用して MSmerge_contents または MSmerge_tombstone 内の行がサブスクライバのパーティションに関連があるかどうかが決定されます。

  3. 行がサブスクライバにまったく関連していない場合 (別のパーティションへの行挿入など)、この行のメタデータは #belongs または #notbelongs には格納されません。行が関連している場合は、次の 2 つの結果が考えられます。

    • MSmerge_contents の行がパーティションに属する挿入であった場合、または MSmerge_contents の行がフィルタ選択に使用された列の値をまったく変更しない更新であった場合、#belongs に 1 行が追加されます。

    • MSmerge_contents の行がフィルタ選択に使用された列の値を変更する (つまり、行を新しいパーティションに移動する) 更新であった場合、または MSmerge_tombstone の行がパーティション内の行の削除を表す場合、#notbelongs に 1 行が追加されます。

注意

事前計算済みパーティションが有効であっても、他のサブスクリプションが変更の受信を開始した後でサブスクリプションが作成された場合は、そのサブスクリプションが初めて同期されるときに SetupBelongs 処理が使用されます。