Windows SharePoint Services との同期で発生するパフォーマンスの問題
サーバーと同期するときには、考慮しなければならないパフォーマンス上の問題がいくつかあります。これらの問題には、待機時間、スループット、帯域幅、ページング、特定のデータセットを返すためのフィルタ処理と並べ替えなど、パフォーマンスに影響する事項が含まれます。
待機時間
待機時間、つまりユーザーが要求を行った後にサーバーから返ってくる情報を受け取るまでの遅延は、ユーザーにとって非常に重要です。要求自体のサイズに制限があるだけでなく、データベースやフロントエンド Web サーバーで要求を処理する時間にも制限があることが多く、きわめて長い要求を行うと要求が拒否される場合があります。
このため、[GetListItemChangesSinceToken] の rowLimit プロパティを使用して要求されるデータ量を毎回制限することは非常に重要ですが、このプロパティを使用すると同期処理の完了にかかる合計時間が増えることも明らかです。
スループット
当然のことながら、要求の処理に必要なサイクルの総量を減らすと待機時間が短縮され、パフォーマンスの向上につながります。ただし、複数のクライアントがあるときには、ひとつのクライアントが他のクライアントに及ぼす悪影響を減少させることがより重要です。ほとんどの場合、複数のクライアントに何らかの処理を実装するより、サーバーに同じ処理の実行を要求する方が、より簡単でシンプル、安全で効果的です。しかし、スループットを増大させるためには、通常は、クライアントで処理した方がよいでしょう。サーバーの方がより大きな処理能力を備えていると思われますが、クライアントではより長い CPU 時間が利用できると考えられるからです。同期クライアントから サーバーに要求されるデータは、できる限り小さくシンプルにする必要があります。
帯域幅
当社では、高帯域幅シナリオの作成を目指していますが、回線に送信されるデータ量を最小限に抑えようとすることも重要です。クライアントから特定の情報が要求されていない場合、要求にその情報が含まれてはなりません。
ページング
完全同期化 (変更トークンなし) を実行する場合、クライアントでは rowLimit パラメータを使用し、返されるアイテムのページあたりの最大数を要求する必要があります。フィルタ処理されたリスト内のアイテム数が、返されるアイテムのページあたりの最大数より多い場合、サーバーは ListItemCollectionPositionNext 属性を返し、次のページの要求に使用します。
最初のページにあるリストの現在の変更トークンのみが返されるので、最初のページに行われた変更は失われません。クライアントでは、変更トークンが最初のページから格納され、以降のページの増分同期化が行われます。
注意
以降のページにリストはなく、アクセス許可、代替 URL、有効時間 (TTL) などのグローバル プロパティも含まれません。
行の制限の使用
rowLimit は、増分同期化でもサポートされていますが (変更トークン供給済み)、増分同期化では、この要素は内部変更ログの処理を制限します。また、ページあたり 100 行という内部制限もあります。返されるアイテム数がこれらの制限を超えないことがクライアントで確実に認識されていて、返されるアイテム数が制限を下回る場合でも、特定の状況では一部の変更の同期が行われない場合があります。これは、更新回数が上限に達した直後に変更ログの処理を停止した場合に発生します。このようなときには、MoreChanges 属性を返し、変更ログに追加の変更があることを示す必要があります。クライアントでは、同期化の次の更新を待つのではなく、返された変更トークンを使用して直ちに追加の変更を要求する必要があります。
rowLimit が増分同期化に及ぼす影響は次のとおりです。
ページあたり 100 行という内部制限があります。返されたアイテムのフィルタ処理に使用できる更新日時インデックスはありません。さらに、SQL サーバーには、クエリで使用できる OR は 160 という制限があり、この上限に近づくとパフォーマンスが低下し始めます。内部制限の 100 行に、クライアントが要求できるフィルタとして 60 行を使用できます。
複数の異なる SQL クエリを作成することもできましたが、そうするとすべてのフィルタ処理と並べ替えを中間層でサポートすることになります。
このため、現在の変更トークンではない変更トークンを返さなければならず、追加の変更は別の呼び出しで処理されることになります。それでも、変更ログ全体を見て、返されるアイテム数が上限を下回る最新の時点を、より正確に判断することはできますが、これは中間層でフィルタ処理を行わない限り完全に正確ではありません。
フィルタ処理と並べ替え
フィルタ処理を行うと、リスト全体ではなく特定のアイテムのセットをリストに返すことができます。フィルタ処理に使用される 2 つの最も一般的なシナリオには、ユーザーがフォルダ内のアイテムのみを受け取るフォルダの同期と、ユーザーが自分に関係のあるアイテムのみを受け取る特定のグループ ボード シナリオがあります。
contains パラメータまたは query パラメータを使用してフィルタ処理を行うことができます。Contains は基本的に CAML (Collaborative Application Markup Language) の Where 句なので、より制限的です。一方、query は、フル クエリ です。特定のシナリオを最適化できるため、Contains を使用した方が安全です。
The Query パラメータは、contains パラメータより強力で柔軟ですが、パフォーマンスに及ぼす影響について理解する必要があります。クエリ パラメータの構築方法によっては、パフォーマンスに次のような影響を及ぼすことがあります。
クライアントでは、インデックスの付いていない列を使用したフィルタ処理は避けなければなりません。そのようにしないなら、ページの取得で、要求されたアイテム数が見つかったリスト全体のスキャンが要求されます。
クライアントでは、列にインデックスが付いてる場合を除き、その列による並べ替えも避けなければなりません。そのようにしないなら、ページの取得で、少なくともフィルタ処理されたデータセット全体の並べ替えが要求されます。
フィルタが、順序に従ったインデックス付きの列と同じ列にない場合、SQL Server では、リスト全体のスキャンが続行され、フィルタ処理されたデータセットの並べ替えが回避されることがあります。
増分同期化には暗黙的フィルタがあります。特定の ID でアイテムを要求することもできます。この場合、クライアントは常に ID 順に並べ替えたアイテムを返す必要があります。データセットの最大数は 100 個に制限されているので、ID と同様に、その他のカテゴリでフィルタ処理を行うこともできます。
フォルダ順にフィルタ処理を行う場合、Folder クエリ オプションを使用できますが、リストは FileLeafRef で並べ替える必要があります。また、再帰クエリは、最初に FileDirRef で並べ替える必要があります。
次のようなコードを使用して、複数のフォルダごとにフィルタ処理を行う方法もあります。
[add code header]
“<Or><BeginsWith><FieldRef Name="FileRef"/><Value Type="Note">Shared Documents/folder1/</Value></BeginsWith><BeginsWith><FieldRef Name="FileRef"/><Value Type="Note">Shared Documents/folder2/</Value></BeginsWith></Or>”.
このコードでは、フォルダ 1 とフォルダ 2 のすべての内容が同期されます。
クライアントでは、このコードを contains パラメータと共に使用し、次のクエリ オプションを追加する必要があります。
“<OptimizeFor>FolderUrls</OptimizeFor> “
これにより、SQL Server クエリを、FileDirRef や FileLeafRef で並べ替えさせ、正しい列に制約を加えて確実に最適化させることができます。