背景と目的
今回は GetAllDocumentsByKey と GetAllEntriesByKey の基本的な挙動を理解することを目的にビューを検索するメソッドとした検証を行います。
ビューを検索し結果のコレクションを作成、そこからエントリを取得して、値を取得する一連の処理のどこで処理時間がかかっているのか、特性を理解します。
今回は、最新の PC を使用して測定し、今どきの実環境に近い結果を目指して検証します。
測定環境
検証に使用する環境は次の通りです。参考までに CrystalMark Retro を使用して測定したベンチマーク結果を添付します。
| CPU | Ryzen 7 9700X | ベンチマーク |
| メモリサイズ | 128 GB | |
| ストレージ | SSD | |
| OS | Windows 11 |
| Server | Domino 14.5 FP1 |
| Client | Notes 14.5 FP1 |
◇ テスト DB
前回紹介したテスト DB を Domino サーバ内に配置します。パフォーマンスに関係しそうな情報を整理すると次の通りです。
| 文書数 | 100,000 文書 |
|
| 検索ビュー | 000000 ~ 099999 の上 3 桁で検索、1 検索当たり 1000 文書がヒット | |
| 文書サイズ | 13 フィールド、188 バイト 値取得用フィールドは 100 バイト |
手順
前回紹介した関数を利用して D1 ~ D3、E1 ~ E5 を順に測定します。関数の引数は次のように設定します。
| viFm | 0 |
ビューを ”000” ~ ”019” の合計 20 回検索 作成されるコレクションは毎回 1000 件 |
| viTo | 19 | |
| viLoop | 50 | コレクションの前から 50 件を取得 |
測定のメインルーチンは次のような感じとなります(抜粋)。このプログラムをエージェントに記述してノーツクライアントから実行して測定します。
|
'測定用ビュー取得 Set nv = ndb.GetView("Category3") nv.AutoUpdate = False Call nv.Refresh() '索引を更新してから測定 '測定パラメータ iFm = 0 iTo = 19 iLoop = 50 '測定実行 For iTest = 1 To 10 '測定回数 'GetAllDocumentsByKey の測定 dD1 = xTest_D1(nv, iFm, iTo, iLoop) dD2 = xTest_D2(nv, iFm, iTo, iLoop) dD3 = xTest_D3(nv, iFm, iTo, iLoop) 'GetAllEntriesByKey の測定 dE1 = xTest_E1(nv, iFm, iTo, iLoop) dE2 = xTest_E2(nv, iFm, iTo, iLoop) dE3 = xTest_E3(nv, iFm, iTo, iLoop) dE4 = xTest_E4(nv, iFm, iTo, iLoop) dE5 = xTest_E5(nv, iFm, iTo, iLoop) '測定結果の記録 ・・・ Next |
測定結果はメッセージボックスで表示するだけでも構いませんが、結果の分析に備えて Excel シートに出力すると便利ですね。
結果
10 回の測定結果から平均値を算出し、棒グラフと積み上げ折れ線グラフで表示します。
ビューを検索して値を取得する検証 3 までの結果を比較すると GetAllDocumentsByKey の方が約 2 倍早い結果となりました。
考察
今回の結果より導くことができるビュー操作の特徴を整理します。
◇ GetAllDocumentsByKey vs GetAllEntriesByKey
結果に記載した通り、GetAllDocumentsByKey 方が 2 倍早い結果となりました。文書を取得する必要がある場合においては、さらに差が開きます。少なくとも今回のテスト環境においては、GetAllDocumentsByKey を使用すべきと言えます。
GetAllEntriesByKey は、ビューのソート順の通りに取得したい、ビューの列値を取得したいという特殊な要件があるときの特殊用途だということだと考えられます。
◇ GetAllDocumentsByKey の挙動
検索結果のコレクションを作成する処理(D1)が最大で、処理時間の 70% を占めていて、残りが値の取得(D3)となっています。コレクションからエントリ(文書)の取得(D2)はほぼ 0 でした。
この結果より、NotesDocumentCollection オブジェクトを作成した時点で内部的に NotesDocument オブジェクトが生成されていることが想定できます。以前の記事 の「検証レポートの要点」で紹介した『GetNextDocument はコレクション内のポインタ移動だけで圧倒的に軽量』の証左と言えますね。
◇ GetAllEntriesByKey の挙動
GetAllEntriesByKey では、検索結果のコレクションを作成する処理(E1)とエントリを取得する処理(E2)で処理時間が記録されています。値の取得では NotesViewEntry で保持している ColumnValues プロパティ、要は配列から値を取得するだけなので処理コストはほぼ 0 となるということになります。
NotesViewEntryCollection と NotesViewEntry のオブジェクト作成のコストが非常に高いことがわかります。この結果も 以前の記事 の「検証レポートの要点」と合致します。
◇ NotesViewEntry から文書のアクセス
値を取得する検証 D3 と E5 はほぼ同じ結果でした。NotesDocument から値を取得する処理においては、文書を NotesViewEntry から取得しても同等の結果が得られることがわかります。
ただ、NotesDocument を取得する処理(E4)でも処理時間が記録されています。この結果より、NotesViewEntry のオブジェクト内に NotesDocument は含まれておらず、Document プロパティアクセス時にオブジェクトを生成していることがわかります。
NotesViewEntry は、ビューからの値取得を目的にチューニングされていると解釈すべきだと考えられます。
まとめと次回の検証
今回の検証は、近年一般的な SSD 環境で検証しました(CPU は AMD なので一般的とはいいがたいのかもしれませんが...)。その結果、GetAllDocumentsByKey の方が約 2 倍早いという結果を得ました。
テストケースは、文書数が 10 万件と多いもの、文書内には必要最小限のデータしかなく軽量で、ビューは 2 列だけのシンプルなものでした。この結果だけで実運用で応用できる検証結果とはいいきれません。
そこで、今回の結果をひとつの基準として、今後は、テスト環境やテストケースを変化させることで、処理時間や特性がどのように変化するのか調査したいと思います。
次回は、文書サイズにより特性が変化するのか確認したいと思います。
| 前回 | Domino 体力測定 |





0 件のコメント:
コメントを投稿