10.9 問合せのパフォーマンスに関するFAQ(よくある質問)

この項では、問合せのパフォーマンスに関してよくある質問と、それに対する回答を提供します。

10.9.1 問合せのパフォーマンスとは何を意味しますか。

回答: 問合せのパフォーマンスは、次の2つの基準で判断します。

  • 応答時間: 個々の問合せに対する応答を取得するまでの時間

  • スループット: 任意の時間内に実行可能な問合せの数(たとえば、1秒当たりの問合せ数)

これら2つの基準は関連していますが、同じものではありません。負荷の高いシステムでは高いスループットが必要ですが、比較的負荷の低いシステムではレスポンス時間を最短にすることが必要になります。また、問合せの全ヒットをユーザーに戻す必要があるアプリケーションもあれば、順序付け済セットの最初の20ヒットのみを戻すだけでよいアプリケーションもあります。この2つの状況を区別することが重要です。

10.9.2 Oracle Text問合せのうち、最速のタイプはどれですか。

回答: 最速タイプの問合せは、次の条件を満たす問合せです。

  • 単一のCONTAINS

  • WHERE句内に他の条件がない。

  • ORDER BY句がない

  • 結果の最初のページのみを戻す(たとえば、最初の10ヒットまたは20ヒット)

10.9.3 表に関する統計を収集する必要がありますか。

回答: はい。表に関する統計を収集しておくと、Oracle Textがコストベースの分析を実行できます。これにより、問合せに最も効率的な実行計画をOracle Textが選択できます。

問合せが常に簡単なテキスト問合せ(構造化述語および結合がない)の場合、Oracle Text索引の統計を削除する必要があります。

10.9.4 データのサイズは問合せにどのように影響しますか。

回答: Oracle Text索引がROWIDを戻す速度は、データの実際のサイズには影響されません。Oracle Text問合せの速度は、索引表からフェッチする必要のある行数、要求されるヒット数、問合せにより生成されるヒット数、およびソートの有無に関係します。

10.9.5 データの形式は問合せにどのように影響しますか。

回答: ドキュメントの形式(ASCIIプレーン・テキスト、HTMLまたはMicrosoft Word)は、問合せ速度には影響しません。ドキュメントは、問合せ時ではなく索引付け時にプレーン・テキストにフィルタ処理されます。

データがクリーンであるかどうかが、問合せに影響します。スペルチェック済で編集作業が行われた出版用のテキストは、スペルミスや略語の多い電子メールなどの非公式のテキストと比べて、合計語彙数がかなり少なくなる傾向にあります(したがって、索引表のサイズも小さくなります)。指定した索引メモリー設定では、余分なテキストがあるとメモリー使用量が多くなり、断片化される行が増え、問合せの応答時間に悪影響を及ぼします。

10.9.6 索引付き検索と機能的検索との違いは何ですか。

回答: カーネルは、索引付き検索および機能的検索を使用してOracle Text索引を問い合せることができます。1つ目の索引付き検索はよく使用される方法であり、カーネルがOracle Text索引に対して特定のテキスト検索を満たすすべてのROWIDを問い合せます。これらのROWIDはまとめて戻されます。

機能的検索では、カーネルが個々のROWIDをテキスト索引に渡し、その特定のROWIDが特定のテキスト基準を満たしているかどうかを問い合せます。機能的検索は、選択性の高い構造の句でよく使用され、Oracle Text索引に対してチェックが必要なROWIDの数はわずかです。次に、機能的検索が有用な検索の例を示します。

SELECT ID, SCORE(1), TEXT FROM MYTABLE
WHERE START_DATE = '21 Oct 1992'         <- highly selective
AND CONTAINS (TEXT, 'commonword') > 0    <- unselective

機能的検索は、Oracle Text問合せを構造化列(たとえば、日時や価格など)で並替える場合や、Oracle Text問合せに非選択的なワードが含まれている場合にも使用されます。

10.9.7 問合せで使用される表はどれですか。

回答: すべての問合せで、索引トークン表が参照されます。この表の名前はDR$indexname$Iという形式で、表にはトークンのリスト(TOKEN_TEXT列)とトークンが発生する行とワードの位置に関する情報(TOKEN_INFO列)が含まれています。

行情報は、外部ROWID値に変換する必要がある内部DOCID値として格納されます。使用する表は、検索のタイプによって異なります。

  • 機能的検索の場合は、$KDR$indexname$Kを使用します。この単純な索引構成表(IOT)には、DOCID/ROWIDのペアごとに1つの行が含まれます。

  • 索引付き検索の場合は、$R表(DR$indexname$R)を使用します。この表のBLOB列にはROWIDの完全なリストが保持されます。

Oracle Database 12cリリース2 (12.2)以降、新しい記憶域属性SMALL_R_ROWが導入され、$R行のサイズを削減できるようになりました。これは、22個の静的な行を作成するのではなく$R行をオンデマンドで移入するため、データ操作言語の競合が減少します。挿入、更新、削除のパラレル操作で同じ$R行をロックしようとすると、競合が生じます。

SQLトレースを調べて$K表または$R表を検索すれば、機能的検索と索引付き検索のどちらが使用されているかが容易に判断できます。

ノート:

これらの内部索引表は、リリースごとに変更されることがあります。アプリケーションではこれらの表に直接アクセスしないことをお薦めします。

10.9.8 $R表の競合の軽減方法

元表の削除および更新操作中の$R競合はこの数年間繰り返されるテーマになってきています。現在、各$R索引には22行の静的行があり、各行には最大2億個の行IDを含めることができます。挿入、更新、削除のパラレル操作で同じ$R行をロックしようとすると、競合が生じます。このリリースの次の拡張機能によって、競合が軽減されます。
  • $R行に含めることができる行IDの最大数は70,000 (各行に格納される1MBのデータに変換される)です。この機能を使用するには、SMALL_R_ROW記憶域属性を設定する必要があります。

  • 事前に決定した行数が移入されるだけでなく、$R行がオンデマンドで作成されます。

10.9.9 テキストのみの問合せは、結果をソートすると遅くなりますか。

回答: はい。低下します。

Oracle Textでは、ソートしない場合は、結果を見つかった順に戻すことができます。アプリケーションで結果を一度に1ページのみ表示する必要がある場合は、このアプローチで速度が向上します。

10.9.10 ORDER BYスコアの問合せを高速化するには、どうすればよいですか。

回答: 関連性スコア(SCORE(n))によるソートは、FIRST_ROWS(n)ヒントを使用すると、高速になります。この場合、Oracle Textは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句に含めないように注意してください。

10.9.11 どのメモリー設定が問合せに影響しますか。

回答: 問合せを行うには、大規模なシステム・グローバル領域(SGA)を取得する必要があります。これらのSGAパラメータは、Oracle Database初期化ファイルに設定できます。これらのパラメータは動的に設定することもできます。

SORT_AREA_SIZEパラメータは、ORDER BY問合せのソートで使用可能なメモリーを制御します。構造化列で頻繁にORDER BYを行う場合は、このパラメータのサイズを増やす必要があります。

関連項目:

10.9.12 長い列を表外のLOBに格納すると、パフォーマンスは向上しますか。

回答: はい。一般に、SELECT文は元表から複数の列を選択します。Oracle Textでは列をメモリーにフェッチするため、元表のラージ・オブジェクト(LOB)などの長い列は、特に、更新頻度が低く、選択される頻度が高い場合、表外に格納する方が効率的です。

LOBを表外に格納するとき、問合せ中にメモリーにフェッチする必要があるのはLOBロケータのみです。表外に格納すると、元表の実質的なサイズが減少します。これにより、Oracle Textで表全体をメモリーにキャッシュしやすくなるため、元表から列を選択するコストが低減し、テキスト問合せが高速になります。

さらに、メモリーにキャッシュされる元表が小さくなれば、問合せ中により多くの索引表データをキャッシュできるため、パフォーマンスが向上します。

10.9.13 複数の列に対するCONTAINS問合せを高速にするには、どうすればよいですか。

回答: 最も高速の問合せタイプは、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つのCONTAINS句より高速に完了します。このような問合せを使用するには、各列のデータをセクション・タグで囲んで、索引付けのためにすべてのデータを1つのテキスト列にコピーする必要があります。これを実行するには、索引付けの前にPL/SQLプロシージャを使用するか、索引付け中にUSER_DATASTOREデータソースを使用して、構造化列とテキスト列を1つのドキュメントに統合します。

10.9.14 問合せに多数の拡張を使用できますか。

回答: 問合せに使用されるワードごとに、索引表から少なくとも1行をフェッチする必要があります。このため、拡張の数はできるだけ少なくします。

ワイルドカード、シソーラス、ステミングおよびファジー・マッチングなどの拡張は、タスクに必要でないかぎり、使用しないようにします。一般的に、問合せに少数の拡張(たとえば10から20)は許容されますが、多数の拡張(80または100)は使用しないでください。問合せ式の拡張の数を判断するには、問合せフィードバック・メカニズムを使用します。

ワイルドカードおよびステミングの問合せの場合は、プリフィックス、サブストリングまたはステム索引を作成すると、問合せ時から索引付け時への語句拡張を回避できます。問合せのパフォーマンスは上がりますが、索引付けの時間が長くなり、ディスク領域が大きくなります。

プリフィックス索引およびサブストリング索引により、ワイルド・カードのパフォーマンスが向上します。プリフィックスとサブストリングの索引付けは、BASIC_WORDLISTプリファレンスを使用して使用可能にします。次の例では、プリフィックスとサブストリングの索引付けに対してワードリスト・プリファレンスを設定します。プリフィックス索引付けについては、Oracle Textで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;

10.9.15 ローカル・パーティション索引はどのような場合に便利ですか。

回答: ローカル・パーティションCONTEXT索引は、パーティション表に対して作成できます。つまり、パーティション表上では、各パーティションに独自の索引表セットがあることを意味します。実際には複数の索引からの結果が必要に応じて組み合され、最終的な結果セットが生成されます。

索引を作成するには、LOCALキーワードを使用します。

CREATE INDEX index_name ON table_name (column_name) 
INDEXTYPE IS ctxsys.context
PARAMETERS ('...')
LOCAL

パーティション表およびローカル索引を使用すると、次のタイプのCONTAINS問合せのパフォーマンスが向上します。

  • パーティション・キー列の範囲検索: この問合せは、パーティション・キーでもある列の特定の値範囲に検索を限定します。

  • ORDER BYパーティション・キー列: これは、最初のn個のヒットのみが必要で、ORDER BY句がパーティション・キーを指定します。

10.9.16 問合せはパラレルに実行する方がよいですか。

回答: システム負荷およびサーバー容量により異なります。パラレルに作成された索引の場合にはパラレル問合せがデフォルト動作ですが、通常、負荷の高いシステムでは問合せの全体的なスループットが低下します。

パラレル問合せは意思決定支援システム(DSS)に最適です。また、これらは、大規模なデータ・コレクションと複数のCPUを備え、同時ユーザー数が少ない分析システムや、Oracle Real Application Clusters (Oracle RAC)ノードにも最適です。

関連トピック

10.9.17 テーマには索引を付けた方がよいですか。

回答: テーマ情報にCONTEXT索引で索引付けすると、時間がかかり、索引のサイズも大きくなります。ただし、テーマ索引を使用すると、ナレッジ・ベースが使用され、ABOUT問合せの精度が上がります。アプリケーションで多くのABOUT問合せを使用する場合は、索引に対してテーマ・コンポーネントを作成してみる価値はあります。ただし、索引付けの時間と記憶領域が余分に必要になります。

関連項目:

ABOUT問合せおよびテーマ

10.9.18 CTXCAT索引はどのような場合に使用すればよいですか。

回答: CTXCAT索引は、テキストが小さなチャンク(わずか数行)になっており、特定の構造化基準(数値や日付など)に従って、検索で結果セットを制限またはソートする場合(あるいはその両方)に、最も効率的に機能します。

たとえば、オンラインのオークション・サイトについて考えます。各競売対象品目には、短い説明、現在の入札価格、オークションの開始日と終了日が含まれています。説明にantique cabinetを含むすべてのレコードが表示され、現在の入札価格は$500未満です。新規に投稿された項目に特に関心があるため、結果をオークション開始時間でソートする必要があります。

CONTEXT索引に対するCONTAINS構造化問合せの場合、この検索は常に効率的とはかぎりません。構造化句およびCONTAINS句に応じて、応答時間が大きく異なる場合があります。これは、構造化句とCONTAINS句の交差またはOracle Text問合せの順序付けが問合せ中に計算されるためです。

構造化情報をCTXCAT索引内に含めると、検索条件にかかわらず、問合せ応答時間は常に最適な範囲内にとどまります。索引付け中にテキスト問合せと構造化問合せの間の相互作用が事前に計算されるため、問合せ応答時間は最適です。

ノート:

Oracle Textの索引タイプCTXCATは、Oracle Database 23aiでは非推奨です。索引タイプ自体とその演算子CTXCATは、将来のリリースで削除される可能性があります。

CONTEXT問合せの代替文法としてCTXCATおよびCTXCAT文法の使用はどちらも非推奨です。かわりに、Oracleでは、CONTEXT索引タイプを使用することをお薦めします。索引タイプは、トランザクション以外のすべての同じ機能を提供できます。CONTEXTでのトランザクションに近い動作は、SYNC(ON COMMIT)または短い期間(できればSYNC(EVERY [time-period]))を使用して実現できます。

CTXCATは、通常、索引のサイズが数メガバイトのときに導入されました。最近の大規模な索引は、CTXCATで管理が困難な場合があります。CTXCATへの索引セットの追加は、CONTEXT索引タイプでFILTER BY列とORDER BY列、またはSDATA列(あるいはその両方)を使用することで、より効率的に実行できます。したがって、CTXCATが適切な選択になることはほとんどありません。Oracleでは、より効率的なCONTEXT索引タイプを選択することをお薦めします。

10.9.19 CTXCAT索引が適さないのは、どのような場合ですか。

回答: 索引作成に要する時間と領域に違いがあります。CTXCAT索引はCONTEXT索引と比べて作成に時間がかかり、使用するディスク領域もかなり多くなります。

ディスク領域に余裕がない場合は、CTXCAT索引が適切かどうかを慎重に考慮してください。

問合せ演算子では、CATSEARCH問合せでは問合せテンプレートを使用して、より豊富なCONTEXT構文を使用できます。CATSEARCH問合せ文法のみを使用する必要があるという古い制限はなくなりました。

ノート:

Oracle Textの索引タイプCTXCATは、Oracle Database 23aiでは非推奨です。索引タイプ自体とその演算子CTXCATは、将来のリリースで削除される可能性があります。

CONTEXT問合せの代替文法としてCTXCATおよびCTXCAT文法の使用はどちらも非推奨です。かわりに、Oracleでは、CONTEXT索引タイプを使用することをお薦めします。索引タイプは、トランザクション以外のすべての同じ機能を提供できます。CONTEXTでのトランザクションに近い動作は、SYNC(ON COMMIT)または短い期間(できればSYNC(EVERY [time-period]))を使用して実現できます。

CTXCATは、通常、索引のサイズが数メガバイトのときに導入されました。最近の大規模な索引は、CTXCATで管理が困難な場合があります。CTXCATへの索引セットの追加は、CONTEXT索引タイプでFILTER BY列とORDER BY列、またはSDATA列(あるいはその両方)を使用することで、より効率的に実行できます。したがって、CTXCATが適切な選択になることはほとんどありません。Oracleでは、より効率的なCONTEXT索引タイプを選択することをお薦めします。

10.9.20 使用可能なオプティマイザ・ヒントおよびそれらの機能はどのようなものですか。

回答: テキスト索引またはBツリー索引を使用した問合せを実行するには、INDEX(table column)オプティマイザ・ヒントを通常の方法で使用します。

NO_INDEX(table column)ヒントを使用すると、特定の索引を使用禁止にすることもできます。

テキスト問合せのFIRST_ROWS(n)ヒントは特別な意味を持ちます。これは、問合せに対する最初のn個のヒットが必要な場合に使用します。DOMAIN_INDEX_SORTヒントをORDER BY SCORE(n) DESCとともに使用すると、Oracleオプティマイザは、ソート済のセットをOracle Text索引から受け入れ、それ以上のソートを実行しないように指示されます。