Performance Design Tips : Category Field参照式
さて、今回も前回に引き続きCategory Fieldの参照式について考えてみることにしましょう。
前回紹介したように、Discussion Templateから作成されたDBは文書数が多くなると、Category選択だけでなく、文書を単に開いて読む場合でもPerformanceが劣化してきます。
再度、Notes/Domino標準のDiscussion Templateの中を見ていくことにします。
ここでは、Notes/Domino R5.xのTemplateを例にします。
@DbColumn("":"nocache"; ""; "By Category"; 1)
という式が選択式に書かれていることは前回も述べた通りです。
まず、この式ですが、"NoCache"指定がありますが、それほどシビアでなければこの指定はPerformanceを悪化させます。
"Cache"指定の場合は、誰かが参照してServerにCacheされているとその情報を使ってくれますが、"NoCache"指定の場合は毎回最新情報を取得する動きになるからです。
では、ちょっと古いですが、R4.xのDiscussion Templateを覗いてみましょう。
私の手元にはR4.xの環境がないのですが、R4.xの頃から使っているDiscussion DBを見てみます。以下のような式が書かれているでしょう。
@If(!@IsNewDoc
& @IsDocBeingLoaded; @Unavailable; @Unique(@DbColumn("";"";"By Category";1)))
ここで重要なのは、以下の部分です。
@If(!@IsNewDoc & @IsDocBeingLoaded; @Unavailable;
この式はNotesの産みの親であるRay Ozzieが書いたと言われている式で、R5のDiscussion Templateからはこの部分が抜け落ちています。
この式の意味としては、「新規の文書ではなく、かつ、文書が読み込まれている時には利用不可にする」ということです。
つまり、Notes/Dominoは文書を開くときもCategoryに指定された値がCategoryに含まれているかどうかを評価する動きをしており、この式を書くことで読み込み字は評価させないようにすることができるのです。
皆さんの設計されたDBでも、@DBColumnや@DBLookupを使って、Categoryと同様に他のViewを参照して値を決めるようなFieldはたくさんあるのではないでしょうか?
そういったFieldの数が多ければ多いほど、このRay Ozzieの式に修正することで驚くほど文書読み込み時のPerformanceが向上するのです。
みなさんのDBのCategory参照式ももう一度見直してみてはいかがでしょうか?
Performance Design Tips : @DBLookupの参照View
さて、前回 に引き続き、今回もView参照式である@DBLookup、@DBColumnについて考えてみることにしましょう。
@DBLookupの式の数を減らすことによってPerformanceを向上させるというのが前回の内容でしたが、今回はその参照先のViewについて考えてみたいと思います。
ここでも、Notes/Dominoの標準のDiscussion Templateを例に見ていきます。
Discussion Templateを使って作成したDBを運用していくと、ある時から、Categoryの選択が非常に遅くなったという経験を持たれている方もいらっしゃるかと思います。
環境によって異なりますが、3000文書位で現象が出る場合もありますし、7000文書位で現象が出る場合もあるでしょう。
では、Category Fieldの式を見てみることにしましょう。
Category Fieldの選択式には以下のような式が書かれています。
@DbColumn("":"nocache"; ""; "By Category"; 1)
これは、Categoryで分類された"By Category"というViewの1列目のCategoryを参照していることになります。
しかし、この"By Category" Viewに含まれている文書は主文書(Main Topic)だけではなく返答文書などもこのViewに存在しています。
つまり、文書数が多くなればなるほど、Viewに含まれる文書が多くなり、それを管理しているIndexの容量も大きくなるわけです。
RDBなどのApplicationでも、参照するTableやViewは小さいほうが効率がいいということはみなさんもご存知でしょう。
Notes/Dominoでも全く同じです。参照するViewのサイズは小さければ小さいほど効率よく動いてくれます。
Discussion TemplateのPerformanceを上げるためには、Category選択のための参照Viewを小さくしてやれば、10000文書を超えてもPerformanceが悪化せずに、ここちよく利用できるものとなるのです。
例えば、Category管理用の文書を別に作成して、その文書だけが含まれたViewを作成してやり、@DBLookupや@DBColumnではそのViewを参照させてやれば、非常にPerformanceがよくなります。
私自身、このように改造したDiscussion DBを持っていますが、32000文書/400MBに膨れ上がった今でも、軽快に動いてくれています。
どうでしょう?
ちょっとした工夫で、Performanceは非常によくなるのです。
みなさんの会社の中で、「遅い」と言われているDBの設計をもう一度見直してみてはいかがでしょうか?
Performance Design Tips : @DBLookup 関数
テーブルから情報を取得するために必ず使う@DBLookup関数がありますが、みなさんもNotes/Dominoの色々なApplicationの中でよく使われていることでしょう。
ここではワークフローApplicationを例に@DBLookup関数について考えてみましょう。
ワークフローで、一般社員が新しく起票をおこなったとしましょう。
その時に何が必要かというと組織の情報や上司の情報です。
Notesで使っているわけですから、NotesIDからその人の所属組織や上司の情報を得て、伝票に保存して利用するわけです。
上司情報を使って承認処理にまわし、承認依頼メールが上司に飛ぶというのがよくあるワークフローApplicationです。
伝票に所属や上司の情報を格納するため、@DBLookupで上司の情報を保持したテーブルDBのViewを参照します。
このような処理はNotes/Dominoで開発されたApplicationには至る所で使われていることでしょう。
では、この@DBLookup関数ですが、みなさん、どのように使われているでしょうか?
Field毎に式を書いて都度参照しているというのも結構多いのではないでしょうか?
このように処理するとNotesはどのような動きをするのかを、みてみましょう。
Notes/Dominoというのは、Client/Server型のシステムの典型的なものです。
Notes Clientはワークフローの伝票を起票する際、まず、伝票のForm設計をClient側に取得します。
取得したFormには、@DBLookupなどの式が、至る所に書かれています。それだけではなく、計算式なども書かれていることでしょう。
Notes Clientはこれらの式を上から順番に実行していきます。
式の中に、@DBLookupが書かれていると、Serverに対してNRPC(Notes RPC:Remote Procedure Call)を使って参照しているViewの中の情報を探して結果を返してくるように依頼します。
@DBLookupが多く書かれていれば書かれているほどServerとのやり取りが多くなり、Performanceは悪くなっていきます。
そんなことは百も承知だとおっしゃる方も多いと思いますが、しかし、貴方は本当に落とし穴に陥っていないでしょうか?
開発している時というのはテスト環境とかで行うため、Local LAN上で動いており、開発している人は実際に本番利用されるネットワーク環境のことなど忘れてしまっていることが多いのです。
@DBLookupを多用すると、Serverとのやり取りが多くなり、Mobileなどで利用する64Kbpsとかの環境では耐えられなくなってきます。
処理の詳細は、NRPC Traceを取得して解析することで、どの処理が重いのかを判別することができるのです。
NRPC Traceについての解説は別の機会にさせていただくことにし、今回は割愛させていただきます。
では、どうすればいいのでしょう?
そうです。Serverへの依頼の回数、即ち@DBLookupの回数を減らすしかありません。
そのためには、テーブル情報のViewの列に必要な情報をカンマとかの区切り文字で入れておき、
@DBLookupで一度で取得してからNotes Client側で値を分解するのです。
そうすることにより、Networkの負荷が軽減されます。
値を分解する時に@Subsetを何度も使わなければならないため、Client側の負荷が上がって遅くなるのでは?と思われる方もいらっしゃるでしょうが、私の経験からは、Network側の時間の方の影響の方が大きいため、このような処理の方が早くなります。
また、Notes 6以降では、@Subsetを使わなくても、取得した値をListに変換してやれば、List[n]でn番目の要素を取り出すことができるため、@Subsetを多用する必要はなくなっています。
さて、どうでしたでしょう?
実際にApplicationが使われる環境を意識して開発すること、これも非常に重要で、常意に忘れてはならないことではないでしょうか?