この項では、問合せのパフォーマンスに関してよくある質問と、それに対する回答を提供します。
回答: 問合せのパフォーマンスは、一般的に次の2つの基準で判断します。
応答時間。個々の問合せに対する応答を取得するまでの時間です。
スループット。任意の時間内に実行可能な問合せの数(たとえば、1秒当たりの問合せ数)です。
この2つは関連していますが、同一ではありません。通常、負荷の高いシステムでは高いスループットが必要ですが、比較的負荷の低いシステムではレスポンス時間を最短にすることが必要になります。また、問合せの全ヒットをユーザーに戻す必要があるアプリケーションもあれば、順序付け済セットの最初の20ヒットのみを戻すだけでよいアプリケーションもあります。この2つの状況を区別することが重要です。
回答: 最速タイプの問合せは、次の条件を満たす問合せです。
単一のCONTAINS
句
WHERE
句内に他の条件がない。
ORDER
BY
句が存在しない。
結果の最初のページのみが戻される(たとえば、最初の10ヒットまたは20ヒット)。
回答: はい。表に関する統計を収集しておくと、Oracle Textがコストベースの分析を実行できます。これにより、問合せに最も効率的な実行計画をOracle Textが選択できます。
問合せが常に簡単なテキスト問合せ(構造化述語および結合がない)の場合、Oracle Text索引の統計を削除する必要があります。
回答: テキスト索引がROWIDを戻す速度は、データの実際のサイズには影響されません。テキスト問合せの速度は、索引表からフェッチする必要のある行数、要求されるヒット数、問合せにより生成されるヒット数、およびソートの有無に関係します。
回答: ドキュメントの形式(ASCIIプレーン・テキスト、HTMLまたはMicrosoft Word)は、問合せ速度には影響しません。ドキュメントは、問合せ時ではなく索引付け時にプレーン・テキストにフィルタ処理されます。
データがクリーンであるかどうかが、問合せに影響します。スペルチェック済で編集作業が行われた出版用のテキストは、スペルミスや略語の多い電子メールなどの非公式のテキストと比べて、合計語彙数がかなり少なくなる傾向にあります(したがって、索引表のサイズも小さくなります)。指定した索引メモリー設定では、余分なテキストがあるとメモリー使用量が多くなり、クリーンなテキストと比べて断片化される行が増え、問合せの応答時間に悪影響を及ぼす可能性があります。
回答: カーネルがテキスト索引に対して問合せを行う方法は2つあります。1つ目は、カーネルがテキスト索引に対して特定のテキスト検索を満たすすべてのROWIDを問い合せる方法であり、これが最も一般的です。これらのROWIDはまとめて戻されます。2つ目の方法では、カーネルが個々のROWIDをテキスト索引に渡し、その特定のROWIDが特定のテキスト基準を満たしているかどうかを問い合せます。
2つ目の方法は機能的検索と呼ばれ、選択性の高い構造の句が存在する場合はこの方法を使用すると、テキスト索引に対してチェックが必要なROWIDの数はわずかです。機能的検索を使用できる検索の例は、次のとおりです。
SELECT ID, SCORE(1), TEXT FROM MYTABLE
WHERE START_DATE = '21 Oct 1992' <- highly selective AND CONTAINS (TEXT, 'commonword') > 0 <- unselective
構造化列(たとえば、日時や価格など)でORDER BYを行い、テキスト問合せが非選択的な場合にも、機能的検索が使用されます。
回答: すべての問合せで、索引トークン表が参照されます。この表の名前は、DR$indexname$I
の形式です。この表には、トークンのリスト(TOKEN_TEXT
列)とトークンが発生する行とワードの位置に関する情報(TOKEN_INFO
列)が含まれます。
行情報は内部DOCID値として格納されます。これらは外部ROWID値に変換する必要があります。これに使用される表は、検索のタイプによって決まります。機能的検索の場合は、$K
表DR$indexname$K
が使用されます。これは、DOCID/ROWIDの各ペアに対する1行を含む、単純な索引構成表(IOT)です。
索引付き検索の場合は、$R
表(DR$indexname$R
)が使用されます。この表のBLOB列にはROWIDの完全なリストが保持されます。
このため、SQLトレースを調べて$K表または$R表を検索すれば、機能的検索と索引付き検索のどちらが使用されているかが容易に判断できます。
回答: はい。低下します。
ソートしない場合、Oracle Textは検索したままの結果を戻すことができます。通常、アプリケーションでは結果を一度に1ページずつ表示するため、この方が高速です。
回答: 関連性スコア(SCORE(n)
)によるソートは、FIRST_ROWS(n)
ヒントを使用すると、非常に高速になります。この場合、Oracle Textはテキスト索引表からフェッチするときに高速の内部ソートを実行します。
このような問合せの例を次に示します。
SELECT /*+ FIRST_ROWS(10) */ ID, SCORE(1), TEXT FROM mytable WHERE CONTAINS (TEXT, 'searchterm', 1) > 0 ORDER BY SCORE(1) DESC;
これを効率的に行うには、1つのCONTAINS
以外の条件をWHERE
句に含めないでください。
回答: 問合せを行うには、大規模なシステム・グローバル領域(SGA)を取得する必要があります。SGA関連のパラメータは、Oracle Database初期化ファイルに設定できます。これらのパラメータは動的に設定することもできます。
SORT_AREA_SIZE
パラメータは、ORDER BY
問合せのソートで使用可能なメモリーを制御します。構造化列で頻繁にORDER BYを行う場合は、このパラメータのサイズを増やす必要があります。
回答: はい。一般に、SELECT
文は元表から複数の列を選択します。Oracle Textでは列をメモリーにフェッチするため、特にこれらの列がほとんど更新されないのに頻繁に選択されるような場合は、元表のLOBなどの長い列は表外に格納する方が効率的です。
LOBを表外に格納するとき、問合せ中にメモリーにフェッチする必要があるのはLOBロケータのみです。表外に格納すると、元表の有効なサイズが減少し、Oracle Textで表全体をメモリーにキャッシュしやすくなります。これにより、元表から列を選択するコストが低減し、テキスト問合せが高速になります。
さらに、メモリーにキャッシュされる元表が小さくなれば、問合せ中により多くの索引表データをキャッシュできるため、パフォーマンスが向上します。
回答: 最も高速の問合せタイプは、WHERE
句にCONTAINS
句が1つあるのみで、その他の条件が含まれていない問合せです。
複数のCONTAINS
を含む次の問合せについて考えます。
SELECT title, isbn FROM booklist WHERE CONTAINS (title, 'horse') > 0 AND CONTAINS (abstract, 'racing') > 0
セクション検索とWITHIN
演算子を次のように使用すると、同じ結果が得られます。
SELECT title, isbn FROM booklist WHERE CONTAINS (alltext, 'horse WITHIN title AND racing WITHIN abstract')>0
この問合せは、さらに高速になります。このような問合せを使用するには、各列のデータをセクション・タグで囲んで、索引付けのためにすべてのデータを1つのテキスト列にコピーする必要があります。これを実行するには、索引付けの前にPL/SQLプロシージャを使用するか、索引付け時にUSER_DATASTORE
データソースを利用して、構造化列とテキスト列を1つのドキュメントに統合します。
回答: 問合せに使用されるワードごとに、索引表から少なくとも1行をフェッチする必要があります。このため、拡張の数はできるだけ少なくします。
ワイルド・カード、シソーラス、ステミングおよびファジー・マッチングなどの拡張は、作業上必要でないかぎり、使用しないようにします。一般的に、問合せに少数の拡張(たとえば10から20)は許容されますが、多数の拡張(80または100)は使用しないでください。問合せ式の拡張の数を判断するには、問合せフィードバック・メカニズムを使用できます。
さらに、ワイルド・カードおよびステミングの問合せの場合は、プリフィックス、サブストリングまたはステム索引を作成すると、問合せ時から索引付け時への語句拡張コストをなくすことができます。問合せのパフォーマンスは上がりますが、索引付けの時間が長くなり、ディスク領域が大きくなります。
プリフィックス索引およびサブストリング索引により、ワイルド・カードのパフォーマンスが向上します。プリフィックスとサブストリングの索引付けは、BASIC_WORDLIST
プリファレンスを使用して使用可能にします。次の例では、プリフィックスとサブストリングの索引付けに対してワードリスト・プリファレンスを設定します。プリフィックス索引付けに対して、3から4文字の長さのトークン・プリフィックスの作成を指定します。
begin
ctx_ddl.create_preference('mywordlist', 'BASIC_WORDLIST'); ctx_ddl.set_attribute('mywordlist','PREFIX_INDEX','TRUE'); ctx_ddl.set_attribute('mywordlist','PREFIX_MIN_LENGTH', '3'); ctx_ddl.set_attribute('mywordlist','PREFIX_MAX_LENGTH', '4'); ctx_ddl.set_attribute('mywordlist','SUBSTRING_INDEX', 'YES');
end
ステム索引付けは、BASIC_LEXER
プリファレンスを使用して使用可能にします。
begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER'); ctx_ddl.set_attribute ( 'mylex', 'index_stems', 'ENGLISH');
end;
回答: ローカル・パーティションCONTEXT
索引は、パーティション表に対して作成できます。つまり、パーティション表上では、各パーティションに独自の索引表セットがあることを意味します。実際には複数の索引がありますが、各索引からの結果が必要に応じて組み合され、最終的な結果セットが生成されます。
この索引は、LOCAL
キーワードを使用して作成します。
CREATE INDEX index_name ON table_name (column_name) INDEXTYPE IS ctxsys.context PARAMETERS ('...') LOCAL
パーティション表およびローカル索引を使用すると、次のタイプのCONTAINS
問合せのパフォーマンスが向上します。
これは、パーティション・キー列の特定の値範囲に検索を限定する問合せです。
これは、最初のn
個のヒットのみが必要で、ORDER BY
句がパーティション・キーを指定する問合せです。
回答: システム負荷およびサーバー容量により異なります。パラレルに作成された索引の場合にはパラレル問合せがデフォルト動作ですが、通常、負荷の高いシステムでは問合せの全体的なスループットが低下します。
一般に、パラレル問合せは、大規模なデータ・コレクションと複数のCPUを備え、同時ユーザー数が少ないDSSや分析システムに特に適しています。
回答: テーマ情報にCONTEXT
索引で索引付けすると、時間がかかり、索引のサイズも大きくなります。ただし、テーマ索引を使用すると、ナレッジ・ベースが使用され、ABOUT
問合せの精度が上がります。アプリケーションでABOUT
問合せが頻繁に使用される場合は、索引に対してテーマ・コンポーネントを作成してみる価値はあります。ただし、索引の作成時間と記憶領域が余分に必要になります。
回答: CTXCAT
索引は、テキストが小さなチャンク(最大で数行)になっており、特定の構造化基準(通常は数値または日付)に従って、検索で結果セットを制限またはソートする必要がある場合(あるいはその両方)に、最も効率的に機能します。
たとえば、オンラインのオークション・サイトについて考えます。各競売対象品目には、短い説明、現在の入札価格、オークションの開始日と終了日が含まれています。この場合、説明に「antique cabinet」が含まれていて、現在の入札価格が$500未満の全レコードを表示するとします。ユーザーが新しく提示される商品に特に興味がある場合は、結果をオークション開始日でソートする必要があります。
このような検索では、CONTEXT
索引に対してCONTAINS
構造化問合せを行っても、構造化句およびCONTAINS
句に応じてレスポンス時間が大きく異なるため、必ずしも効率的ではありません。これは、構造化句とCONTAINS
句の共通部分またはテキスト問合せの順序付けが問合せ時に計算されるためです。
価格や日付などの構造化情報をCTXCAT
索引内に含めると、検索条件にかかわらず、問合せ応答時間は常に最適な範囲内にとどまります。これは、テキストと構造化問合せ間の相互作用が、索引付け時に事前に計算されるためです。この結果、問合せ応答時間が最適になります。
回答: 索引作成に要する時間と領域に違いがあります。CTXCAT
索引はCONTEXT
索引と比べて作成に時間がかかり、使用するディスク領域もかなり多くなります。ディスク領域に余裕がない場合は、CTXCAT
索引が適切かどうかを慎重に考慮する必要があります。
問合せ演算子に関しては、CATSEARCH
問合せでは問合せテンプレートを使用して、より豊富なCONTEXT
文法を使用できるようになっています。CATSEARCH
問合せ文法のみを使用する必要があるという古い制限はなくなりました。
回答: オプティマイザ・ヒントINDEX(table column)
を通常の方法で使用すると、テキスト索引またはBツリー索引を使用した問合せを実行できます。
NO_INDEX(table column)
ヒントを使用すると、特定の索引を使用禁止にすることもできます。
さらに、テキスト問合せではFIRST_ROWS(n)
ヒントが特殊な意味を持ち、問合せで最初のn
個のヒットが必要な場合に使用できます。DOMAIN_INDEX_SORT
ヒントをORDER BY SCORE(n) DESC
とともに使用すると、Oracleオプティマイザは、ソート済のセットをテキスト索引から受け入れ、それ以上のソートを実行しないように指示されます。