事前計算済みパーティションによるパラメータ化されたフィルタのパフォーマンス最適化

事前計算済みパーティションは、フィルタ選択されたマージ パブリケーションのパフォーマンス最適化に使用されます。フィルタ選択されたパブリケーションで論理レコードを使用する場合にも事前計算済みパーティションが必要になります。論理レコードの詳細については、「論理レコードによる関連行への変更のグループ化」を参照してください。

サブスクライバがパブリッシャに同期するとき、パブリッシャはサブスクライバのフィルタを評価して、サブスクライバのパーティションまたはデータセットに属する行を識別する必要があります。フィルタ選択されたデータセットを受け取る各サブスクライバに対して、パブリッシャの変更内容のパーティション メンバシップを決定する処理をパーティション評価と呼びます。事前計算済みパーティションがない場合は、特定のサブスクライバに対する最後のマージ エージェントの実行以降、パブリッシャのフィルタ選択された列に対して加えられた変更ごとにパーティション評価を実行する必要があります。さらに、パブリッシャと同期するすべてのサブスクライバについて、この処理を繰り返し行う必要があります。

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

事前計算済みパーティションを使用するだけでなく、スナップショットを事前に生成するか、最初の同期時にサブスクライバからスナップショットの生成および適用を要求できるようにしてください。これらのオプションの両方またはどちらかを使用して、パラメータ化されたフィルタを使用するパブリケーションに対するスナップショットを提供します。これらのオプションのどちらかを指定しないと、bcp ユーティリティを使用するのではなく、一連の SELECT ステートメントおよび INSERT ステートメントを使用してサブスクリプションが初期化されます。この処理は、かなり低速で実行されます。詳細については、「パラメータ化されたフィルタを使用したマージ パブリケーションのスナップショット」を参照してください。

事前計算済みパーティションを使用するには

上記のガイドラインに準拠するすべての新規および既存パブリケーションでは、事前計算済みパーティションが既定で有効になっています。この設定は SQL Server Management Studio を使用して変更することもできますし、プログラムを使用して変更することもできます。詳細については、次のトピックを参照してください。

事前計算済みパーティションを使用するための要件

以下の要件が満たされる場合、新規に作成されるマージ パブリケーションは既定で事前計算済みパーティションが有効になります。また、既存のパブリケーションは自動的にこの機能が使用できるようにアップグレードされます。パブリケーションが要件を満たさない場合は、事前計算済みパーティションを使用できるようにパブリケーションを変更できます。要件を満たすアーティクルと要件を満たさないアーティクルが混在している場合は、パブリケーションを 2 つ作成し、そのうちの 1 つで事前計算済みパーティションを有効にすることを検討してください。

フィルタ句の必要要件

  • HOST_NAME() や SUSER_SNAME() など、パラメータ化された行フィルタで使用する関数はパラメータ化されたフィルタ句に直接記述してください。ビューまたは動的関数の内部で入れ子にすることはできません。これらの関数の詳細については、「HOST_NAME (Transact-SQL)」、「SUSER_SNAME (Transact-SQL)」、および「パラメーター化された行フィルター」を参照してください。

  • パーティションの作成後、各サブスクライバに返される値を変更することはできません。たとえば、フィルタで HOST_NAME() を使用する場合 (および HOST_NAME() の値を上書きしない場合)、サブスクライバでコンピュータ名を変更しないでください。

  • 結合フィルタに動的関数 (HOST_NAME() や SUSER_SNAME() など、同期するサブスクライバによって異なる値に評価される関数) を含めることはできません。動的関数はパラメータ化された行フィルタでのみ使用できます。

  • 非決定的関数はフィルタ句の中では使用できません。非決定的関数の詳細については、「決定的関数と非決定的関数」を参照してください。

  • 結合フィルタ句またはパラメータ化されたフィルタ句で参照されるビューに動的関数を含めることはできません。

  • 循環結合フィルタのリレーションシップをパブリケーションに格納することはできません。

データベースの照合順序

  • 事前計算済みパーティションを使用する場合、比較を行う際にはテーブルや列ではなくデータベースの照合順序が常に使用されます。以下のシナリオについて考えてみます。

    • 大文字と小文字が区別される照合順序のデータベースに、大文字と小文字が区別されない照合順序のテーブルが格納されています。

    • テーブルに ComputerName 列が含まれており、パラメータ化されたフィルタ内でサブスクライバのホスト名と比較されます。

    • この列が "MYCOMPUTER" という値の行と "mycomputer" という値の行が 1 つずつテーブルに含まれています。

    サブスクライバが "mycomputer" というホスト名で同期する場合、このサブスクライバが受け取る行は 1 行のみです。データベースの照合順序により、大文字と小文字を区別して比較されるからです。事前計算済みパーティションを使用しない場合、サブスクライバは両方の行を受け取ります。テーブルの照合順序により、大文字と小文字は区別されないからです。

事前計算済みパーティションのパフォーマンス

事前計算済みパーティションを使用する場合、サブスクライバからパブリッシャに変更内容をアップロードするときに若干のパフォーマンス コストがかかります。ただし、マージ処理に必要な時間の大部分は、パーティションの評価とパブリッシャからサブスクライバへの変更内容のダウンロードに費やされます。したがって、全体としてはパフォーマンスが大きく向上します。パフォーマンスがどの程度向上するかは、同時に同期するサブスクライバの数、およびあるパーティションから別のパーティションに行を移動する同期ごとの更新数によって異なります。