本文へジャンプ

ソフトウェア Lotus Lotus Developer Domain 製品別技術情報 Lotus Notes/Domino 7 > 
 

IBM Lotus Notes/Dominoでのより速い検索のためのコーディング

   
 
コンテンツ
エラーをトラップする
検索の頻度を最小限にする
キャッシュを正しく使用する
ドロップダウン・リストの落とし穴を避ける
ドロップダウン・リストの代わりにボタンおよびpicklistを使用する
ドロップダウン・リストの代わりにレイアウト領域(またはポップアップ)を使用する
@Evalを使用してコードをクリーンアップする
1回の検索で複数のフィールドを取得する
より速い検索ビューにする
プロフィール文書を使用する
検索データベースを使用する
まとめ
リソース
筆者について
ご意見ご要望をお寄せ下さい

Raphael Savir, Principal Developer, LS Development Corporation

レベル:中級
原文の掲載:2007年 3月 13日
原文はこちら (US)

IBM Lotus Notes/Dominoで、より速い検索をコーディングする11のヒントを理解しましょう。IBM Lotus Notes/Dominoで使用されている@DbLookup @式を筆者が調べた結果に基づき、新規アプリケーションのコーディングおよび既存のアプリケーションでのパフォーマンスのトラブルシューティングを行うときに開発者が使用できる新しいヒントを紹介します。

この記事では、おそらくIBM Lotus Notes/Dominoで最も使用されている@関数である@DbLookupを取り上げます。IBM Lotus Notes/Dominoアプリケーションの現在の開発者は、この式を使わずにアプリケーションを作成することなど想像できないでしょう。15年を超えるパフォーマンス・テストおよびお客様のトラブルシューティングによると、この式はアプリケーションの複数のフォームで一般的に使用されていて、1つのフォームで数十回も使用されることがしばしばありました。

しかし、同時に、これらの@DbLookup式にはパフォーマンスの問題も頻繁に発生することが示されています。私たちは、洗練されたエンタープライズ・アプリケーションが、これらの式に関連するあまりにも遅いパフォーマンスによって仮想的に停止してしまう場面を見てきました。

この記事では、ほとんどすべてのアプリケーションのスピードアップを保証する11のヒントについて説明します。これらのヒントは、1行だけの変更から、@DbLookup式へのアプローチ方法を劇的に変えてしまうケースまで広い範囲にわたりますが、いずれも年月をかけて有効性が証明されているものです。

IBM Lotus Notes/Domino開発の知識をある程度持っていることを前提として説明を進めるため、@DbLookup式の基本的な引数などについては触れません。

この記事では、さまざまな例を使用してヒントの有効性を示します。説明を簡単にするために、アプリケーションを1つだけ使用します。連絡先(Contact)フォームとチケット(Ticket)フォームを持つヘルプ・デスク(Help Desk)アプリケーションです。このアプリケーションの基本的なワークフローは次のようになります。まず、お客様から連絡があると、チケット文書を作成します。次に、お客様の会社および名前に関する情報を取得し、ドロップダウン・リストから適切な会社名と連絡先名を選択します。また、連絡の適切なカテゴリー(たとえば、製品ヘルプ、営業など)を選択します。このアプリケーションでは、@DbLookup式が役に立つ次のようなケースがすぐに思い浮かびます。

  • すべての会社のリストから、会社名を選択する
  • その会社のすべての連絡先のリストから、お客様の名前を選択する
  • あらかじめ決められた、または動的な問題カテゴリーのリストから、問題カテゴリーを選択する

エラーをトラップする

エラーがないことを願っていても、エラーのトラップは必要となります。@DbLookup式はキーおよび返されるデータ用のユーザー入力に依存することが多いので、@DbLookup式では扱いにくいエラーがしばしば発生します(この記事では、@DbLookupは@DbLookup式と@DbColumn式の両方を示します)。つまり、ある時点では式が正しく機能していても、翌日には正しく機能しないことがあります。開発者にとって、これは常に困難な状況です。

たとえば、ある会社の会社名が、異なる連絡先文書で3、4とおりのスペルで入力されているケースを考えます(「LSDevelopment Corporation」と「LS Development Corporation」など)。その会社の各連絡先の名前を検索するときに、「LSDevelopment Company」と入力すると、一致するものは見つからないでしょう。

より正確にキーを入力する方法はありますが(たとえば、ドロップダウン・リストを使用する)、説明のために、厳密な開発手法を使用しても @DbLookupはエラーを返すことがあると仮定しましょう。

エラーをチェックする基本的な方法は、リスト1に示すコードを記述することです。


リスト1. エラー・チェック
v := @DbLookup(“Notes”; “”; “(Lookup-ContactsByCompany)”; CompanyName; 
“ContactName”);
@If(@IsError(v); “The program cannot find any contacts for this 
company”; v)

このコードでは、検索を実行し、その後でエラー条件をチェックします。エラーが存在する場合は、問題があることをユーザーに示すテキスト・ストリングを返します。それ以外の場合は、検索結果の値を返します。

これはパフォーマンスには関係しませんが、多くのアプリケーションに見られるあまりにも基本的な問題なので、無視することはできません。特別なヒントと考えてください。


上に戻る

検索の頻度を最小限にする

検索式の次のコードを検討します。

@If(@IsError(@DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1); “There are no
company names”; @DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1))

これは、検索を2回実行している非常に一般的なミスで、パフォーマンスの観点から問題となります。最初の検索で検索結果が完全にキャッシュされるので、2回目の検索はフリー(負担にならない)と考えているのでしょうが、これは正しくありません。結果は確かにキャッシュされるため、2回目の検索は最初の検索よりも速くなりますが、フリーではありません。そのような方法でコーディングする機能的な理由はないため、以下のようにコーディングする必要があります。

v := @DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1);
@If(@IsError(v); “There are no company names”; v)

不必要な検索が生じるもう1つの誤りとして、以下のような場合に計算を行う計算結果フィールドの検索式があります。

  • 文書が初めて作成されるとき
  • 編集モードの文書を更新するさまざまなボタンが押されるとき
  • 文書が保存されるとき
  • 以降の日付に文書が読み込みモードで開かれるとき
  • 以降の日付に文書が編集モードで開かれるとき
  • 以降の日付に文書が保存されるとき

最も頻度が高いのは、文書を初めて作成するときに、検索を1回だけ実行するケースです。この場合は、フィールドを「作成時の計算結果」にして、それ以上の計算を防ぎます。

これとは別に、文書を編集モードで開くたびに、検索を実行するケースが考えられます。この場合は、式を以下のように書き換えます。

@If(@IsDocBeingEdited; “”; @Return(FieldName));
v := @DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1);
@If(@IsError(v); “There are no company names”; v)

ここで、FieldNameはこの式が置かれているフィールドの名前です。文書が編集モードでロードされていない場合は、式はそのままの値を保持し、実行を停止します(図1参照)。それ以外の場合は、以前と同様に@DbColumnを実行します。

図1. キーワード式


上に戻る

キャッシュを正しく使用する

もう1つの一般的な誤りとして、NoCache引数の使い方を誤解していることが挙げられます。つまり、データが重要であるほどNoCacheを使用することの重要性が増すと考えるのは誤りです。実際には、検索を実行する頻度に対して、データの変更頻度はどうなのかを考慮して判断します。

たとえば、検索するデータがあまり変更されない場合は(月ごとの変更など)、検索式にNoCacheを使用することの必要性はまったく考えられません。この記事の例では、参照用に数個のカテゴリーをチケット文書に作成したものとします。リストはアプリケーションの所有者によって維持され、新製品がリリースされたとき、新規のビジネス・ベンチャーが参入したときなど、リストは数カ月ごとに更新されるぐらいです。

一方、連絡してきたお客様をチケット文書で検索するケースを考えます。このお客様が1時間に2回連絡してくる場合は、2つめのチケット文書で名前の検索をミスすることはあり得ないでしょう。名前のリストは、前回の検索でキャッシュされているからです。このような種類のアプリケーションでは、ヘルプ・デスクのスタッフが1日中データベースを開いたままにしていることをよく見かけるので、キャッシュに対応した検索を長時間キャッシュされたままにすることは容易です。


上に戻る

ドロップダウン・リストの落とし穴を避ける

私たちは長年、深刻なパフォーマンスの問題を抱えるフォームを見てきました。その原因の中でも1番に挙げられるのがドロップダウン・リストで、理由は2つあります。ドロップダウン・リストは大きなリストを検索することがよくあること、そして読み込みモードでも計算を行うためです。

アプリケーションで簡単なテストを実行できます。遅いと感じられるフォームを使用する文書を読み込みモードで開きます。文書が開くときに、画面を注意深く見て、一時停止する場所を見つけてそれを書き留めます。画面が変わるまで一瞬なのでたいへんな作業かもしれませんが、他の人に手伝ってもらい、一方がフィールド・ラベルを読み上げ、もう一方が書き留めるとよいでしょう。次に、IBM Lotus Domino Designerでこのフォームを開き、これらの場所の直下に何があるのかを調べます。ほとんどの場合、それは@DbLookup式をともなうドロップダウン・リストでしょう。一体、何が起きているのでしょうか。

文書が読み込みモードで開かれるとき、すべての@DbLookup式が検証されます。文書が読み込みモードなので、これらの式は実際には値を返しませんが、動作を実行するので時間がかかります。ドロップダウン・リストではさらに悪いことに、ユーザーが編集モードに切り替えたときのために、選択可能な値がキーワード・フィールドに生成されます。ユーザーが編集モードに切り替えるまで待って実行すれば、時間のコストをユーザーに押しつけられる、と考えるかもしれませんが、Lotus Notesではそのように動作しません。興味深いことに、これは正にWebブラウザーでの動作です。まったく同じフォームに対しても、このように動作します。

ドロップダウン・リストのクリーンアップとして実績のある1つの方法を紹介します。3つの異なる機能を組み合わせて不要な検索を避ける方法です。それぞれは簡単な作業ですが、3つをすべて行う必要があります。

最初に、ドロップダウン・フィールドの式で、以下の式を使用します。

@If(@IsDocBeingEdited; “”; @Return(FieldName));
v := @DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1);
@If(@IsError(v); “There are no company names”; v)

これは、「検索の頻度を最小限にする」で説明されているものと同様で、文書が読み込みモードの場合は、キーワード・ドロップダウン・リストが検索を実行するのを防止します。ユーザーが編集モードで文書を開いたときは、もちろんドロップダウン・リストは通常どおり計算を行います。ここで、ユーザーが読み込みモードから編集モードに切り替えたときに、検索が確実に計算されるようにしなければなりません。これを次の2つのステップで実行します。

ドロップダウン・フィールドのプロパティーで、「文書の更新時に選択肢を更新」属性を有効にします(図2参照)。これにより、文書の更新が強制されている限り、ユーザーが読み込みモードから編集モードに切り替えたときに、キーワード・ドロップダウン式が再計算されます。

図2. ドロップダウン・フィールドのプロパティー

最後に、フォームのPostmodechangeイベントに(図3参照)、ユーザーが読み込みモードから編集モードに切り替えたときに更新を強制する次のコードを含めます。

If source.EditMode Then Call source.Refresh

図3. Postmodechangeイベント


上に戻る

ドロップダウン・リストの代わりにボタンおよびpicklistを使用する

場合によっては、あまりにもたくさんのドロップダウン・リストがあり、リストのサイズが大きく、使用頻度も高いため、合理的なソリューションとして、主要フォームでドロップダウン・リストの使用を停止する以外の方法が考えられないケースもあります。使用する際の判断方法として、以下の質問を自分自身に問いかけてみます。

  • 文書のライフサイクルで、何回その文書が読まれるのか?
  • 文書が何回編集されるのか?
  • 文書の編集時に、これらの検索は何回必要なのか?

次のような回答がよくあります。「一般に、文書は10回ほど読まれますが、編集されるのは数回です。これらの編集のうち、ドロップダウン・リストが使用されるのは1回だけです」もちろん、使用方法に応じて回数は常に変わりますが、これらは検討に値する質問です。文書が頻繁に編集されるのに、検索の必要性がほとんどない場合は、前のセクションの方法では不十分でしょう。実際に、リストは1回しか必要ないのに、ユーザーが編集モードにいるときは常にドロップダウン・リストが再計算されるからです。このような場合はボタンの使用を考慮し、ボタンをpicklistとともに使用することもあります。

ボタンを使用することの利点は、フィールドから検索式を削除できることです。フィールドはドロップダウン・リストではなく、FieldNameの式(その後の例にある式、ProblemCategory)を持つ通常のテキスト・フィールド(多くの場合、作成時の計算結果)にします。混乱を避けるために、読み込みモードのときはボタンを非表示にしますが、編集モードでボタンをクリックすると、リスト2に示す式が使用されます。


リスト2. ボタンの式

tlist := @DbColumn("Notes"; ""; "(Lookup-Categories)"; 1);
list := @Unique(@Explode(tlist; "~"));
@If(@IsError(list); @Return(@Prompt([Ok]; "Error"; "The program was unable to lookup the 
Problem Categories.")); "");

dv := @If(ProblemCategory = ""; @Subset(list; 1); ProblemCategory);
v := @Prompt([OkCancelListMult]; "Problem Category"; "Choose one or more problem 
categories for this ticket."; dv; list);

FIELD ProblemCategory := v;

@Promptおよび@DbLookupの代わりに@Picklistを使用すると、さらにパフォーマンスを改善できます。この方法の欠点は、ポップアップのレイアウトと背後にあるデータをあまり制御できないことです。例として、リスト3のコードを参照してください。


リスト3. @Picklistの使用

v := @PickList( [CUSTOM] ; “” ; “(Lookup-Categories)” ; “Problem Category” ; 
“Choose one or more categories from the list.” ; 1 )
result := @If(@IsError(v); “The program was unable to lookup the Problem Categories”; v);
FIELD ProblemCategory := result;

上に戻る

ドロップダウン・リストの代わりにレイアウト領域(またはポップアップ)を使用する

検索の規模および頻度に基づき、アプリケーションにとって前のセクションが適切なアプローチであると判断した場合でも、必要な制御が得られないことがあります。このような場合は、ダイアログ・ボックスの使用を考慮します。@式またはLotusScriptによってダイアログ・ボックスを表示し、1つのダイアログ・ボックス内で複数の検索を実行できます。相互に関連する複数の検索がフォーム内にある場合、ダイアログ・ボックスは優れたソリューションになります。たとえば、ユーザーが会社を選択した後は、その会社内の連絡先のリストを表示します。さらに、3番目のドロップダウン・リストには、その連絡先に関する未解決のチケットの件名の行が含まれています。このようなケースでは、前のセクションで説明したようなボタンを配置するとよいでしょう。ただし、リスト4に示すコードを使用します。


リスト4. ダイアログ・ボックスの使用
Dim w as NotesUIWorkspace
flag = w.DialogBox ( "(Dialog-CompanyLookup)", True, True, False, True, 
False, False,
"Company Name", doc, False, False, False )

ここでは各パラメーターの詳細については説明しませんが、開発者用のヘルプ・リファレンスをリスト5に示します。


リスト5. ヘルプ・リファレンス
flag = notesUIWorkspace.DialogBox( form$ , [autoHorzFit] , [autoVertFit] , 
[noCancel] , 
[noNewFields] , [noFieldUpdate] , [readOnly] , [title$] , [notesDocument] , 
[sizeToTable] ,
[noOkCancel] , [okCancelAtBottom] )

「(Dialog-CompanyLookup)」フォームで、レイアウト領域を挿入し、@IsDocBeingEditedを考慮せずにすべてのドロップダウン・フィールドを配置できます。ユーザーは、ボタンをクリックし、ダイアログ・ボックスを表示したときにのみ、検索の待ち時間を負担します。 ダイアログ・ボックスを使用するときは、以下の点も考慮してください。

  • 保存しない一時的なLotus Notes文書を作成し、前のコード例の[notesdocument]引数として使用すると役に立つ場合があります。これにより、LotusScriptを使用してより洗練された検索を実行するリストを作成し、ダイアログ・ボックスに配置できます。たとえば、過去3カ月以内にコンタクトを取った会社だけを参照する、といったことが可能です。
  • ダイアログ・ボックス・フォームで検証チェックを行い、入力データが検証されない限りユーザーを主要文書に戻さないようにすると便利な場合があります。これにより、ユーザーが何度もダイアログ・ボックスに戻る手間を軽減できます。
  • グラフィック、ヘルプ・テキストなどを追加することにより、プレーンなドロップダウン・リストまたは@Promptボックスよりも、ダイアログ・ボックスをより美しく機能的に見せることができます。
  • アプリケーションをWebに移植するときは、JavaScriptのポップアップ・ウィンドウでダイアログ・ボックスをたいへん簡単に置き換えることができます。レイアウト領域自体はブラウザーに提供できませんが、<div>タグ(ページ内の任意の場所にコンテンツのブロックを配置できるHTMLコード)または表でレイアウトを近似できます。
  • また、ネストされた表および[sizeToTable]引数を使用すると、Lotus Notesクライアントでダイアログ・ボックスを魅力的な外観にできます。このフォームは、より簡単にWebに移植できます。

上に戻る

@Evalを使用してコードをクリーンアップする

これまでに、@DbLookup式を使用した@Ifステートメントで埋められた長い@式のコードをときどき見ることありました。このような式は維持しにくく、適切なエラー・チェックを実施したり(「エラーをトラップする」のセクションを参照)、不要な検索を回避することがより困難になる可能性があります。リスト6に示すように、@Evalを使用すると、このような問題を防ぐために役立ちます。


リスト6. @Evalの使用
companyLookup := {@DbColumn(“Notes”; “”; “(Lookup-Companies)”; 1);};
contactLookup := {@DbLookup(“Notes”; “”; “(Lookup-ContactsByCompany)”; 
CompanyName; “ContactName”);};

@If(someCondition = 1; @Eval(companyLookup); @Eval(contactLookup))

このコードは、@Ifステートメントに達するまで検索の実行を防止します。つまり、あらかじめすべての検索をセットアップし、これらに適切な変数名を割り当てておきます。そして、必要に応じて@Evalを使用してこれらを呼び出すことができます。


上に戻る

1回の検索で複数のフィールドを取得する

異なるデータ・ポイントを取得するために、同じ文書に対して検索を複数回実行している場合は、これらのデータを結合して検索ビューの1つの列に入れることを考慮してください。たとえば、1つの文書から次のデータ・ポイントを取得するものとします。

  • ContactName
  • ContactPhone
  • ContactAddress1
  • ContactAddress2
  • ContactCity
  • ContactState
  • ContactZip

これを行うために、7つのフィールドを配置して、各フィールドで検索を実行する方法があります。この場合、ContactNameフィールドの式はリスト7に示すコードのようになります。


リスト7. ContactNameフィールドの式
v := @DbLookup(“Notes”; “”; “(Lookup-ContactsByCompany)”; CompanyName; 
“ContactName”);
@If(@IsError(v); @Return(“The program could not locate that 
document.”); v);

また、ContactPhoneフィールドの式はリスト8に示すコードのようになります。


リスト8. ContactPhoneフィールドの式
v := @DbLookup(“Notes”; “”; “(Lookup-ContactsByCompany)”; CompanyName; “
ContactPhone”);
@If(@IsError(v); @Return(“The program could not locate that 
document.”); v);

他の各フィールドの式も同様です。

7回の検索が同じビュー内の同じ文書に対して実行される場合でも、検索を1回にした方が、7回の検索よりもかなり速いパフォーマンスを得られます。これを実現する1つの方法として、2番目の列にリスト9に示す式が含まれる検索ビューをセットアップします。


リスト9. 2番目の列を持つ検索ビューのセットアップ

@If(ContactName = “”; “NA”; ContactName) + “~” + 
@If(ContactPhone = “”; “NA”; ContactPhone) + “~” +  
@If(ContactAddress1 = “”; “NA”; ContactAddress1) + “~” + 
@If(ContactAddress2 = “”; “NA”; ContactAddress2) + “~” + 
@If(ContactCity = “”; “NA”; ContactCity) + “~” + 
@If(ContactState = “”; “NA”; ContactState) + “~” + 
@If(ContactZip = “”; “NA”; ContactZip); 

次に、フォーム内に BigLookupという非表示フィールドを作成し、リスト10に示す式をこのフィールドに設定します。


リスト10. ContactsByCompanyの検索
v := @DbLookup(“Notes”; “”; “(Lookup-ContactsByCompany)”; 
CompanyName; 2);
@If(@IsError(v); @Return(“The program could not locate that 
document.”); v);

今度は、ContactNameフィールドの式はリスト11に示すようになります。


リスト11. ContactNameの検索
tv := @Explode(BigLookup; “~”);
v := tv[1];
@If(@IsError(v); @Return(“The program could not locate that document.”); v = “NA”; “”; v);

ContactPhoneについては、リスト12のコードを参照してください。


リスト12. ContactPhoneの検索
tv := @Explode(BigLookup; “~”);
v := tv[2];
@If(@IsError(v); @Return(“The program could not locate that document.”); v = “NA”; “”; v);

他の各フィールドの式も同様です。

この方法では、以下の2つの点に注意してください。

  • ビューの列式では、""の代わりに"NA"を使用しました。このようにしないと@Explodeは空の値を省略し、7つの値よりも短いリストが生成され、これが問題となるからです。
  • 各フィールドの式では、"NA"の代わりに""を使用しました。これは、エラー・メッセージなので、自由に決められます。

上に戻る

より速い検索ビューにする

@式言語またはLotusScriptのどちらを使用しているかにかかわらず、ビューに対するどのような検索のパフォーマンスも、ビューのサイズとスピードに依存します。ここでは、検索ビューのパフォーマンスを最適化するために役に立ついくつかのヒントを集めてみました。

専用の検索ビューにする

実稼働環境では、ごく一般的な1つのビューの索引を作成する(更新する)ために、約100ミリ秒かかることが明らかになっています。これは、15分ごとにサーバーが各検索ビューを更新するために、1/10秒未満の時間しかかからないことを意味します。もちろん、これらの時間は概算であり、各アプリケーションおよびサーバーによって大きく異なります。しかし、長年にわたるこのデータの研究から、たとえいくつかの検索ビューを追加してもパフォーマンス面での影響はほとんどない、と私たちは確信しています。検索用に1つの専用ビューを追加することにより、そのビューでの検索の待ち時間のパフォーマンスを改善できます。

ビューの設計を合理化する

ビューが特定の文書からのデータの検索だけに使用される場合は、ビューの設計から以下の要素を削除できます。

  • 装飾用のすべてのフォントと色
  • アクション・バーのすべてのボタン
  • ビューのイベント内のすべてのLotusScriptコード
  • プロフィール文書へのすべての参照
  • 余分な列。データを返す列は残し、返さない列は削除します。
  • ビューの列用の複数のソート・オプション。たとえば、ユーザーがビューにアクセスしない場合は、昇順および降順にソートする必要はありません。サイズが増加するだけです。
  • @DbLookupによって返される選択肢リストを制限する読者名フィールド。これらは、パフォーマンスに大きく影響します。

また、カテゴリーを使用することによっても、列をソートし、同じ機能を検索用に提供できますが、ビューの索引作成はより速くなります。

データを合理化する

設計を最小化することに加え、ビューに表示されるデータを最小化することも考慮してください。推奨事項は以下のとおりです。

  • 可能であれば、積極的にデータをアーカイブします。業務上のニーズは設計上のどの考慮事項よりも優先しますが、2番目のLotus Notes データベースにデータをアーカイブし、たとえば、ユーザーから読み取り専用でアクセスさせることも可能です。これを行うことにより、最初のデータベースで多数の機能がスピードアップするとともに、ビュー内のデータが制限され、ビューも高速になります。
  • ビューの選択式を慎重に最適化し、本当に必要なデータだけが表示されるようにします。
  • 表示はしないが、ビューの索引に含める必要がある返答文書を選択しないようにしてください。「SELECT Form = "Main" | @IsResponseDoc」のような選択式は、不用意にこれを行います。表示する返答文書だけを含める場合は、代わりに@DocDescendantsを使用します。
  • 不要なデータを削除する例として、お客様のアプリケーションで、過去30日分のデータだけが検索ビューに必要なのに、それよりもずっと長い期間(たとえば、2年間)のデータをデータベースに保持していたケースがありました。ビューで時間および日付に関連する式を使用することは意味がありません(速度が非常に遅くなります)。しかし、過去30日よりも古い文書をマークするエージェントを毎週実行し、文書にフラグを設定する方法には意味があります。このようにすると、選択式はフラグをチェックするだけで、ビューの速度を低下させる大部分の文書を除外することができます。
  • 検索に使用されないデータを表示しないようにします。

エントリーの重複を避けるために「索引にユニークなキーを作成する」を使用する

これは、特定のビューのサイズを劇的に削減する優れた手法です。検索で大量の重複値が取得され、@Unique (または、LotusScriptの同等の機能)を使用して値を取り出している場合は、この機能を使用できます。このような場合は、「索引にユニークなキーを作成する」オプションを有効にすると(図4参照)、ビューの索引は、検出されたテキスト・ストリングの最初のインスタンスだけを表示します。

ただし、ソート列が複数値フィールドを参照している場合は、このオプションの使用には注意してください。このようなケースでは、Lotus Dominoサーバーのバージョンが6.xの場合は、@Implode(MultiValueField; "~")を使用し、検索式で@Unique(@Explode(@DbColumn(); "~"))を使用して、正しい固有値のセットを取得してください。Lotus Domino 7を使用している場合は、サーバーが論理的に判断してすべての固有値を表示するので、この点は問題になりません。この機能を使用しているビューは、おそらくビューの更新時に通常よりもサーバーの作業が増えるので、索引の速度が多少遅くなります。ビューに表示される文書の数が劇的に削減される場合にのみ、この機能を使用してください。多くのアプリケーションでは、この機能を使用したときにビューのサイズが1/100に削減されると、この機能の価値が生じます。

図4. 「ビューのプロパティー」ダイアログ・ボックス


上に戻る

プロフィール文書を使用する

複数のユーザーによって更新されず、更新も頻繁に行われないリストがある場合、これらの値をプロフィール文書に格納すると、値を取得する速度が向上します。プロフィール文書でリストを手動で更新するか、通常の文書でリストを更新し、その後プロフィール文書に移動するかにかかわらず、ユーザーはビューをキャッシュするときよりも効率よく、プロフィール文書をキャッシュできます。このため、繰り返し実行する検索が速くなります。

しかし、複数のユーザーがリストを更新する場合は、おそらくプロフィール文書は適切ではありません。複数の更新によって相互に上書きされ、複製/保存の競合が発生する可能性があるからです。


上に戻る

検索データベースを使用する

大規模なアプリケーションでは、個別の検索データベースを使用することがしばしばあります。おそらくこれは、検索するデータがあまりにもたくさんあるため、データと必要なビューをメイン・データベースから切り離すことに意味がある、という考えに基づいていると思われます。これは、確かに一理ありますが、実際のところ、通常は得るものよりも失うものの方が多いでしょう。検索データを個別のデータベースに保持すべき場合と、メイン・データベース内に保持することに意味がある場合のヒントを以下に示します。

  • 同じリストにアクセスする複数のアプリケーションが存在する場合は、これらのリストを個別のデータベースに格納することに意味があります。
  • 検索するデータが大量にあり、これらのデータに複数のフォームが必要な場合は、メインのユーザー・データベースからデータを切り離すことに意味があります。
  • 一方、検索データが単一のフォームを使用し、文書数も数百程度であれば、メイン・データベースに与える影響は無視できます。この場合は、メンテナンスおよびパフォーマンスの両面で利点があるため、メイン・データベースで検索を維持することをお勧めします。

問題となるのは、パフォーマンスが最優先され、少数の小さなリストにアクセスする複数のデータベースがあるケースです。このようなケースでは、これらのリストを個別の検索データベースで維持するとよいでしょう。ただし、LotusScriptエージェント(または、Lotus Enterprise Integrator)によって、各メイン・データベースに移植します。これは、維持が面倒になりますが、最高のパフォーマンスを発揮します。


上に戻る

まとめ

この記事で紹介したヒントが、新しいアプリケーションをコーディングするとき、または既存のアプリケーションでパフォーマンス問題をトラブルシューティングするときに、新たな手法として利用されることを望んでいます。動的な検索は、ほとんどのアプリケーションで重要な機能として用いられています。それゆえ、動的な検索のパフォーマンスへの影響を最小にすることが、長年にわたって使用される優れたプログラムにするための最良の方法となります。


リソース

学ぶために

議論する

筆者について

Raphael Savirは、LS Development Corporation(http://www.lsdevelopment.com)の主任開発者であり、1990年代の初めから、Lotus Notes/Dominoアプリケーションの開発およびアプリケーションのパフォーマンス問題の分析に取り組んでいます。Lotusphereおよび他のコンファレンスのさまざまな機会で、これらのトピックについて講演しています。




上に戻る