10 Oracle Textのチューニング
Oracle Textには、問合せと索引付けのパフォーマンスを改善する方法が用意されています。
この章のトピックは、次のとおりです:
10.1 統計を使用した問合せの最適化
統計を使用して問合せを最適化する場合は、問合せ表および索引に関して収集された統計を使用して、その問合せを最も効率的に処理できる実行計画が選択されます。一般に、問合せパフォーマンスの改善が必要な場合は、元表に関する統計を収集することをお薦めします。統計を使用して最適化を行うと、CONTAINS
述語の選択性およびコストをより正確に見積ることができるため、より適切な実行計画が選択されます。
オプティマイザは、次のパラメータに基づいて最適な実行計画を選択します。
-
CONTAINS
述語の選択性 -
同じ問合せに含まれるその他の述語の選択性
-
CONTAINS
述語を処理したときのCPUコストとI/Oコスト
次の各項では、統計を拡張可能問合せオプティマイザで使用する方法を説明します。
ノート:
Oracle Text索引などの、ドメイン索引に関する統計のインポートおよびエクスポートは、DBMS_STATS
パッケージではサポートされていません。統計のインポートおよびエクスポートの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
関連項目:
CONTAINS
問合せ演算子の詳細は、『Oracle Textリファレンス』を参照してください
10.1.1 統計の収集
デフォルトでは、Oracle Textはコストベース・オプティマイザ(CBO)を使用し、問合せに対する最適な実行計画を決定します。
オプティマイザを使用して最適なコストを見積るには、問い合せた表の統計を計算します。
ANALYZE TABLE <table_name> COMPUTE STATISTICS;
あるいは、次のように表のサンプルの統計を見積ります。
ANALYZE TABLE <table_name> ESTIMATE STATISTICS 1000 ROWS;
または
ANALYZE TABLE <table_name> ESTIMATE STATISTICS 50 PERCENT;
統計の収集は、DBMS_STATS.GATHER_TABLE_STATS
プロシージャを使用してパラレルに行うこともできます。
begin DBMS_STATS.GATHER_TABLE_STATS('owner', 'table_name', estimate_percent=>50, block_sample=>TRUE, degree=>4) ; end ;
これらの文は、table_name,
に関連付けられたすべてのオブジェクトの統計を収集します。オブジェクトには、その表の列とその表に関連付けられたすべての索引(Bツリー、ビットマップまたはテキスト・ドメイン)も含まれます。
表の統計を再収集するには、ANALYZE
文を必要な回数入力するか、DBMS_STATS
パッケージを使用します。
テキスト・ドメイン索引の統計を収集することによって、Oracle DatabaseのCBOでは、次のタスクを実行できます。
-
CONTAINS
述語の選択性の見積り -
Oracle Text索引を使用したときのI/OコストとCPUコスト(ドメイン索引を使用して
CONTAINS
述語を処理するときのコスト)の見積り -
CONTAINS
の起動ごとのI/OコストとCPUコストの見積り
CONTAINS
述語の選択性がわかっていると、構造化問合せなど、複数の述語が含まれた問合せを行う場合に役立ちます。このように、CBOでは、ドメイン索引を使用してCONTAINS
を評価するか、あるいはCONTAINS
述語をポスト・フィルタとして適用するかを、より適切に判断できます。
関連項目:
-
ANALYZE
文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 -
DBMS_STATS
パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
10.1.2 統計による問合せ最適化の例
次の構造化問合せは、統計を最適化する例です。
select score(1) from tab where contains(txt, 'freedom', 1) > 0 and author = 'King' and year > 1960;
次のことを前提にしています。
-
author列は
VARCHAR2
型で、year列はNUMBER
型です。 -
author
列にはBツリー索引があります。 -
構造化述語
author
は、CONTAINS
述語およびyear
述語と比較してきわめて厳密です。つまり、構造化述語(author = 'King')は、year
述語およびCONTAINS
述語と比較して、かなり少ない数の行(たとえば、それぞれ1000行および1500行に対して5行)を戻すと想定します。
このような状況の場合、Oracle Textでは、最初に構造化述語(author = 'King')にBツリー索引のレンジ・スキャンを行い、次にROWIDで表アクセスを行ってから、Bツリーの表アクセスから戻された行に他の2つの述語を適用することで、この問合せをより効率的に行うことができます。
ノート:
Oracle Text索引の統計が収集されていない場合、CBOはCONTAINS
述語の選択性と索引コストが低いものとみなします。
10.1.3 統計の再収集
索引を同期化した後、単一の索引の統計を再収集して、コストの見積りを更新できます。
同期化の前に元表が再解析された場合は、同期化の後に表全体を再解析しなくても、索引を解析するのみで十分です。
統計を再収集するには、次のいずれかの文を入力します。
ANALYZE INDEX <index_name> COMPUTE STATISTICS;
ANALYZE INDEX <index_name> ESTIMATE STATISTICS SAMPLE 50 PERCENT;
10.2 応答時間短縮のための問合せの最適化
デフォルトでは、Oracle Textは問合せが最短時間ですべての行を戻すように、スループットの問合せを最適化します。
ただし、多くの場合(特にWebアプリケーションの場合)、問合せを応答時間が短縮されるように最適化する必要があります。これは大きなヒットリストからできるだけ短い時間で、最初の数個のヒットのみを取得する必要があるためです。
次の各項では、応答時間が短縮されるようにCONTAINS
問合せを最適化する方法を説明します。
10.2.1 問合せの応答時間に影響するその他の要因
問合せの応答時間に影響を与える要因として、次のものが考えられます。
-
表統計の収集
-
メモリー割当て
-
ソート
-
元表に存在するラージ・オブジェクト(LOB)列
-
パーティション化
-
並列性
-
問合せで語句を拡張する回数
関連項目:
10.2.2 FIRST_ROWS(n)ヒントによるORDER BY問合せの応答時間の短縮
ORDER BY
問合せの最初のいくつかの行が必要な場合は、コストベースであるFIRST_ROWS(n)
ヒントを使用することをお薦めします。
ノート:
FIRST_ROWS(n)
ヒントはコストベースであるため、使用する前に表に関する統計を収集しておくことをお薦めします。
FIRST_ROWS(n)
ヒントは、最初のn行をできるだけ短時間で受け取る必要がある場合に使用します。たとえば、次のPL/SQLブロックでは、カーソルを使用して問合せの最初の10ヒットを取り出し、FIRST_ROWS(n)
ヒントを使用して応答時間が短縮されるように最適化しています。
declare cursor c is select /*+ FIRST_ROWS(10) */ article_id from articles_tab where contains(article, 'Omophagia')>0 order by pub_date desc; begin
for i in c loop insert into t_s values(i.pk, i.col); exit when c%rowcount > 11; end loop;
end; /
c
カーソルは、omophagiaというワードを含むソートされたROWIDを戻すSELECT
文です。コードがカーソル内をループして、最初の10行を取り出します。取り出された行は、一時t_s
表に格納されます。
FIRST_ROWS(n)
ヒントを指定した場合、オプティマイザは上位n個のヒットを戻すコストが低い場合に、Oracle Text索引に対してROWIDをスコア順で戻すように指示します。
このヒントがない場合、Oracle Text索引によりCONTAINS
述語を満たすすべての行がソートされていない順序で戻された後、Oracle DatabaseによりROWIDがソートされます。結果セット全体を取り出すと時間がかかります。
この問合せでは、最初の10ヒットのみが必要なため、ヒントを使用することでパフォーマンスが向上します。
ノート:
FIRST_ROWS(n)
ヒントは、問合せで最初の数個のヒットのみが必要な場合に使用します。結果セット全体が必要な場合は、パフォーマンスの低下につながるため、このヒントは使用しないでください。
10.2.3 DOMAIN_INDEX_SORTヒントを使用した応答時間の短縮
また、DOMAIN_INDEX_SORT
ヒントを使用して応答時間を短縮することもできます。FIRST_ROWS(n)
の場合と同じように、応答時間が短縮されるように問合せが最適化されている場合は、Oracle Textは最初の数行を最短時間で戻します。
たとえば、このヒントは次のように使用できます。
select /*+ DOMAIN_INDEX_SORT */ pk, score(1), col from ctx_tab where contains(txt_col, 'test', 1) > 0 order by score(1) desc;
ただし、このヒントはルールベースのみです。つまり、Oracle Textでは、ORDER BY
句を満たす索引を常に選択します。このヒントにより、CONTAINS
句の選択性が非常に高い問合せでは、パフォーマンスが最善にはならないことがあります。そのような場合は、完全にコストベースのFIRST_ROWS(n)
ヒントを使用することをお薦めします。
10.2.4 ローカル・パーティションCONTEXT索引を使用した応答時間の短縮
データをパーティション化し、ローカル・パーティション索引を作成すると、問合せのパフォーマンスが向上します。パーティション表では、各パーティションに独自の索引表セットがあります。実際には複数の索引がありますが、結果が必要に応じて組み合され、最終的な結果セットが生成されます。
LOCAL
キーワードを使用して、CONTEXT
索引を次のように作成します。
CREATE INDEX index_name ON table_name (column_name) INDEXTYPE IS ctxsys.context PARAMETERS ('...') LOCAL
パーティション化された表および索引を使用すると、次のような問合せのパフォーマンスが向上します。
-
パーティション・キー列の範囲検索: この問合せは、パーティション・キーでもある列の特定の値範囲に検索を限定します。たとえば、日付範囲に対する次の問合せについて考えます。
SELECT storyid FROM storytab WHERE CONTAINS(story, 'oliver')>0 and pub_date BETWEEN '1-OCT-93' AND '1-NOV-93';
日付範囲が制限されている場合は、1つのパーティションを検索するだけで問合せが満たされる可能性があります。
-
ORDER BYパーティション・キー列: これは、最初の
n
個のヒットのみが必要で、ORDER BY
句がパーティション・キーを指定します。次のように、price
列に対するORDER BY
問合せで最初の20ヒットをフェッチする場合を考えてみます。SELECT * FROM (
SELECT itemid FROM item_tab WHERE CONTAINS(item_desc, 'cd player') >0 ORDER BY price) WHERE ROWNUM < 20;
この例では、表はpriceによりパーティション化されており、最初のパーティションからのヒットを取得すれば問合せが満たされる可能性があります。
10.2.5 スコア順のローカル・パーティション索引を使用した応答時間の短縮
ローカル・パーティション索引に対するDOMAIN_INDEX_SORT
ヒントにより、特にスコア順にした場合にパフォーマンスが大幅に低下することがあります。結果をソートする前に、全パーティションにまたがる問合せの全ヒットを取得する必要があります。
かわりに、DOMAIN_INDEX_SORT
ヒントを使用するときにインライン・ビューを使用します。DOMAIN_INDEX_SORT
ヒントを使用すると、次のような条件下で、ローカル・パーティション表の問合せパフォーマンスが向上します。
-
SCORE()
句による順序を含むOracle Text問合せ自体がインライン・ビューとして表されている場合。 -
インライン・ビュー内のOracle Text問合せに
DOMAIN_INDEX_SORT
ヒントが含まれている場合。 -
インライン・ビューに対する問合せに、ビューからフェッチする行数を制限する
ROWNUM
述語が含まれている場合。
たとえば、パーティション表doc_tab
に対して、次のOracle Text問合せとローカルOracle Text索引が作成されます。
select doc_id, score(1) from doc_tab where contains(doc, 'oracle', 1)>0 order by score(1) desc;
上位20行のみを取り出す場合は、この問合せを次のように再作成します。
select * from (select /*+ DOMAIN_INDEX_SORT */ doc_id, score(1) from doc_tab where contains(doc, 'oracle', 1)>0 order by score(1) desc) where rownum < 21;
関連項目:
EXPLAIN PLAN
文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
10.2.6 問合せフィルタ・キャッシュを使用した応答時間の短縮
Oracle Textには、問合せ結果のキャッシュに使用できる、問合せフィルタ・キャッシュというキャッシュ・レイヤーがあります。問合せフィルタ・キャッシュは、問合せ間で共有が可能です。キャッシュされた問合せ結果を複数の問合せで再利用して、問合せの応答時間を短縮できます。
キャッシュする問合せ結果を指定するには、ctxfiltercache
演算子を使用します。次の例では、この演算子を使用して、common_predicate
問合せの結果をキャッシュに格納しています。
select * from docs where contains(txt, 'ctxfiltercache((common_predicate), FALSE)')>0;
この例では、common_predicate
問合せの結果がキャッシュされ、new_query
問合せによって再利用されます。そのため、問合せの応答時間が短縮されます。
select * from docs where contains(txt, 'new_query & ctxfiltercache((common_predicate), FALSE)')>0;
ノート:
ノート:
CTXFILTERCACHE
問合せ演算子は、問合せでよく使用される式を高速化するために設計されました。Oracle Databaseリリース20cでは、この機能は他の内部の改善によって置き換えられています。CTXFILTERCACHE
演算子は非推奨です(また、そのオペランドを通過して通常の問合せとして実行されます)。それらには機能がないため、ビューCTX_FILTER_CACHE_STATISTICS
も記憶域属性QUERY_FILTER_CACHE_SIZE
も非推奨です。
関連項目:
詳細は、『Oracle Textリファレンス』を参照してください。
-
ctxfiltercache
演算子 -
query_filter_cache_size
基本記憶域属性 -
ctx_filter_cache_statistics
ビュー
10.2.7 CONTEXT索引のBIG_IOオプションを使用した応答時間の短縮
Oracle Textに用意されているBIG_IO
オプションを使用すると、IO操作を多用するCONTEXT
索引の問合せパフォーマンスを改善できます。問合せパフォーマンスが向上するのは、主として回転ディスク上に格納されているデータの場合であり、SSDに格納されているデータについてはあまり効果がありません。
BIG_IO
オプションを有効にすると、CONTEXT
索引では一意のトークン・テキストごとに1つのラージ・オブジェクト(LOB)データ型を伴うトークン・タイプ・ペアが作成されます。テキストが同じでトークン・タイプが異なるトークンは、$I
表で対応する行が異なります。
BIG_IO
オプションが有効になっている索引には、SecureFile LOBとして作成されたトークンLOBが必要です。これにより、データが複数のブロックに順次格納されます。この方法により、問合せで短い読取りを何度も実行するかわりに、連続した長い読取りを実行できるため、問合せの応答時間が短縮されます。
ノート:
SecureFilesを使用する場合は、COMPATIBLE
設定を11.0以上に設定する必要があります。また、自動セグメント領域管理(ASSM)の表領域にLOBを作成する必要があります。既存のOracle Text索引をSecureFilesに移行する場合は、ASSM表領域を使用します。既存の索引をSecureFilesに移行しやすくするために、$I表にのみ影響する記憶域プリファレンスを提供するようにALTER INDEX REBUILD
を拡張できます。
BIG_IO
索引オプションを指定してCONTEXT
索引を作成するには、まずBIG_IO
記憶域属性の値をYES
に設定して基本記憶域プリファレンスを作成し、CONTEXT
索引の作成時にこの記憶域プリファレンスを指定します。
次の例は、mystore
基本記憶域プリファレンスを作成し、そのBIG_IO
記憶域属性の値をYESに設定します。
exec ctx_ddl.create_preference('mystore', 'BASIC_STORAGE'); exec ctx_ddl.set_attribute('mystore', 'BIG_IO', 'YES');
BIG_IO
オプションを無効にするには、BIG_IO
記憶域属性の値をNO
に設定して既存の記憶域プリファレンス(mystore
)を更新してから、索引を再構築します。
exec ctx_ddl.set_attribute('mystore', 'BIG_IO', 'NO'); alter index idx rebuild('replace storage mystore');
警告:
メタデータ置換操作を使用して、BIG_IO
索引オプションを無効にしないでください。索引で矛盾が生じる場合があります。
索引を再構築せずにパーティション索引でBIG_IO
オプションを有効にするには、BIG_IO
記憶域属性の値をYES
に設定して基本記憶域プリファレンスを変更し、ctx_ddl.replace_index_metadata,
を使用してグローバル索引メタデータを置き換えてから、パーティション索引表のパーティションごとにREBUILD
モードでoptimize_index
をコールします。
次の例では、idx
パーティション索引に対してBIG_IO
オプションを有効にします。
exec ctx_ddl.set_attribute('mystore', 'BIG_IO', 'YES'); exec ctx_ddl.replace_index_metadata('idx', 'replace metadata storage mystore'); exec ctx_ddl.optimize_index('idx', 'rebuild', part_name=>'part1');
ノート:
BIG_IO
オプションのみを有効にして既存の索引表を変更するプロシージャでは、データの再索引付けは行われません。
ノート:
BIG_IO
索引オプションは連続した長い読取りを実行するので、BIG_IO
索引オプションを使用する問合せでは、必要なプログラム・グローバル領域(PGA)のメモリーが多くなります。
10.2.8 CONTEXT索引のSEPARATE_OFFSETSオプションを使用した応答時間の短縮
Oracle Textに用意されているSEPARATE_OFFSETS
オプションを使用すると、主に1つのワードまたはブールの問合せを対象としてIO操作を多用するCONTEXT
索引の問合せパフォーマンスを改善できます。
SEPARATE_OFFSETS
オプションは、タイプTEXT
のトークンに対して異なるポスト・リスト構造を作成します。DOCID、頻度、情報の長さ(オフセット情報の長さ)およびオフセットをポスト・リストに分散させるかわりに、SEPARATE_OFFSETS
オプションではDOCIDと頻度をすべてポスト・リストの最初に格納し、情報の長さとオフセットをすべてポスト・リストの最後に格納します。ポストの先頭にあるヘッダーには、DOCIDとオフセットの間の境界点に関する情報が含まれています。DOCIDとオフセットを分離すると、データを読み取る問合せの時間が短くなるため、問合せの応答時間が短縮されます。
SEPARATE_OFFSETS
オプションのパフォーマンスが最大限に発揮されるのは、BIG_IO
オプションと組み合せたときに、きわめて長いポストを持つトークンを対象とした場合です。
SEPARATE_OFFSETS
オプションを指定してCONTEXT
索引を作成するには、まずSEPARATE_OFFSETS
記憶域属性の値をT
に設定して基本記憶域プリファレンスを作成します。次に、CONTEXT
索引の作成時にこの記憶域プリファレンスを指定します。
次の例は、mystore
基本記憶域プリファレンスを作成し、そのSEPARATE_OFFSETS
記憶域属性の値をTに設定します。
exec ctx_ddl.create_preference('mystore', 'BASIC_STORAGE'); exec ctx_ddl.set_attribute('mystore', 'SEPARATE_OFFSETS', 'T');
SEPARATE_OFFSETS
オプションを無効にするには、SEPARATE_OFFSETS
記憶域属性の値をF
に設定して既存の記憶域プリファレンス(mystore
)を更新してから、索引を再構築します。
exec ctx_ddl.set_attribute('mystore', 'SEPARATE_OFFSETS', 'F'); alter index idx rebuild('replace storage mystore');
警告:
索引で矛盾が生じるので、SEPARATE_OFFSETS
索引オプションの無効化にメタデータ置換操作は使用しないでください。
索引を再構築せずにパーティション索引でSEPARATE_OFFSETS
オプションを有効にするには、SEPARATE_OFFSETS
記憶域属性の値をT
に設定して基本記憶域プリファレンスを変更し、ctx_ddl.replace_index_metadata,
を使用してグローバル索引メタデータを置き換えてから、パーティション索引表のパーティションごとにREBUILDモードでoptimize_index
をコールします。
次の例では、idx
パーティション索引に対してSEPARATE_OFFSETS
オプションを有効にします。
exec ctx_ddl.set_attribute('mystore', 'SEPARATE_OFFSETS', 'T'); exec ctx_ddl.replace_index_metadata('idx', 'replace storage mystore'); exec ctx_ddl.optimize_index('idx', 'rebuild', part_name=>'part1');
ノート:
SEPARATE_OFFSETS
オプションのみを有効にして既存の索引表を変更するプロシージャでは、データの再索引付けは行われません。
10.2.9 CONTEXT索引のSTAGE_ITAB、STAGE_ITAB_MAX_ROWS、STAGE_ITAB_PARALLELオプションを使用した応答時間の短縮
Oracle Textに用意されているSTAGE_ITAB
オプションを使用すると、ほぼリアルタイムの索引付けのために挿入、更新および削除の操作を多用するCONTEXT
索引および検索索引について、問合せのパフォーマンスを改善できます。STAGE_ITAB
オプションは、検索索引についてのみ、デフォルトの索引オプションとなります。
STAGE_ITAB
索引オプションを使用しない場合は、新しいドキュメントをCONTEXT
索引に追加するたびに、ドキュメントを検索可能にするためにSYNC_INDEX
がコールされます。このコールは、$I
表に新しい行が作成されるため、$I
表で断片化が大きくなります。その結果、問合せのパフォーマンスが低下します。
STAGE_ITAB
索引オプションを有効にすると、次の処理が行われます。
-
新しいドキュメントに関する情報は、
$I
表ではなく$G
ステージング表に格納されます。このストレージによって$I
表は断片化しなくなるため、問合せパフォーマンスが低下しません。 -
$H
Bツリー索引は、$G
表に作成されます。$G
表と$H
Bツリー索引は、$I
表と$X
Bツリー索引と同等です。
$G
表の行数が記憶域設定STAGE_ITAB_MAX_ROWS
(デフォルトは1万)を超えると、$G
表から$I
表に行が自動的にマージされます。MERGE
最適化モードで索引最適化を実行することによって、$G
から$I
への行の即時マージを強制することもできます。
ノート:
$G
表は、KEEP
プールに格納されます。問合せパフォーマンスを改善するには、十分なKEEP
プール・メモリーを割り当て、新しいstage_itab_max_rows
オプションを使用して十分な大きさの$G
表を維持する必要があります。
STAGE_ITAB
索引オプションを指定してCONTEXT
索引を作成するには、まずSTAGE_ITAB
記憶域属性の値をYES
に設定して基本記憶域プリファレンスを作成します。次に、CONTEXT
索引の作成時にこの記憶域プリファレンスを指定します。
次の例は、mystore
基本記憶域プリファレンスを作成し、そのSTAGE_ITAB
記憶域属性の値をYES
に設定します。
exec ctx_ddl.create_preference('mystore', 'BASIC_STORAGE'); exec ctx_ddl.set_attribute('mystore', 'STAGE_ITAB', 'YES');
ALTER INDEX
文の再構築オプションを使用すれば、パーティション化されていない既存のCONTEXT
索引に対してSTAGE_ITAB
索引オプションを有効にすることもできます。
alter index IDX rebuild parameters('replace storage mystore');
パーティション化されていないCONTEXT
索引に対してSTAGE_ITAB
オプションを無効にするには、STAGE_ITAB
記憶域属性の値をNO
に設定して既存の記憶域プリファレンス(mystore
)を更新してから、索引を再構築します。
exec ctx_ddl.set_attribute('mystore', 'STAGE_ITAB', 'NO'); alter index idx rebuild('replace storage mystore');
この操作は、MERGE
最適化モードを使用して最適化プロセスを実行してから、$G
表を削除します。
ALTER INDEX
文の再構築オプションを、パーティション化されているCONTEXT
索引に使用して、STAGE_ITAB
オプションの有効化と無効化を行うことはできません。
次の例は、CONTEXT
パーティション索引idx
に対してSTAGE_ITAB
オプションを有効にします。
alter index idx parameters('add stage_itab');
次の例は、CONTEXT
パーティション索引idx
に対してSTAGE_ITAB
オプションを無効にします。
alter index idx parameters('remove stage_itab');
$G
の行数がOracle Database 12cリリース2 (12.2)では100万、Oracle Databaseリリース18cでは10万を超えている場合は、索引の同期中に、$G
の内容が自動的に$I
に移動されました。Oracle Databaseリリース20c以降では、デフォルトでは、$G
の行数が1万を超えている場合は、索引の同期中に$G
の内容が自動的に$I
に移動されます。この値は、STORAGE
プリファレンスのSTAGE_ITAB_MAX_ROWS
属性により制御されます。
ノート:
CONTEXT
索引にSTAGE_ITAB
索引オプションを使用するには、g_index_clause
およびg_table_clause
BASIC_STORAGE
プリファレンスを指定する必要があります。
$G
表の断片化が進むと、問合せのパフォーマンスが低下します。低下を回避するために、Oracle Databaseリリース18c以降、Oracle Textではすべての索引またはパーティションに対する自動バックグラウンド最適化マージ機能が提供されています。自動バックグラウンド最適化マージを有効にするには、STAGE_ITAB
記憶域プリファレンス属性をTRUE
に設定し、STAGE_ITAB
属性を使用する記憶域プリファレンスで索引を作成する必要があります。
デフォルトでは、Oracle Databaseリリース18cにアップグレードする前に、索引でSTAGE_ITAB
を有効化した場合、STAGE_ITAB_AUTO_OPT
は有効化されません。既存の索引でSTAGE_ITAB
およびAUTO_OPTIMIZE
が有効になっている場合は、STAGE_ITAB_AUTO_OPT
を有効化する前にAUTO_OPTIMIZE
を無効にする必要がありますOracle Databaseリリース19c以降では、自動バックグラウンド最適化マージのSTAGE_ITAB_AUTO_OPT
は、デフォルトではTRUE
に設定されています。STAGE_ITAB_AUTO_OPT
をFALSE
に設定した場合は、そのマージはSYNC INDEX
の一部として実行されます。AUTO_OPTIMIZE
を使用するかわりにSTAGE_ITAB
およびSTAGE_ITAB_AUTO_OPT
をTRUE
に設定することをお薦めします。
ノート:
Oracle Databaseリリース20cでは、プロシージャADD_AUTO_OPTIMIZE
およびREMOVE_AUTO_OPTIMIZE
と、ビューCTX_AUTO_OPTIMIZE_INDEXES
、CTX_USER_AUTO_OPTIMIZE_INDEXES
およびCTX_AUTO_OPTIMIZE_STATUS
は非推奨です。
次の例は、mystore
基本記憶域プリファレンスを作成し、そのSTAGE_ITAB_AUTO_OPT
記憶域属性の値をTRUE
に設定します。
exec ctx_ddl.create_preference('mystore', 'basic_storage');
exec ctx_ddl.set_attribute('mystore', 'stage_itab', 'TRUE');
exec ctx_ddl.set_attribute('mystore', 'stage_itab_auto_opt', 'TRUE');
exec ctx_ddl.set_attribute('mystore', 'stage_itab_parallel', 16);
関連項目:
BASIC_STORAGE
の詳細は、『Oracle Textリファレンス』を参照してください
10.3 スループット向上のための問合せの最適化
スループット向上のために問合せを最適化すると、デフォルトではすべてのヒットが最短時間で戻されます。
次に、スループット向上のために問合せを明示的に最適化する方法を示します。
-
CHOOSEモードおよびALL ROWSモード: デフォルトでは、
CHOOSE
モードおよびALL_ROWS
モードで問合せを最適化します。Oracle Textでは、すべての行が最短時間で戻されます。 -
FIRST_ROWS(n)モード:
FIRST_ROWS(n)
モードでは、可能な場合、テキスト・ドメイン索引でスコア順にソートされた行が戻されるようにすることで応答時間を短縮するよう、Oracle Databaseのオプティマイザが最適化を行います。これは、FIRST_ROWS(n)
ヒントを使用する場合のデフォルトの動作です。FIRST_ROWS(n)
でスループットを最適化するには、DOMAIN_INDEX_NO_SORT
ヒントを使用します。スループットの向上とは、すべての問合せ行を最短時間で取得することです。次の例では、スコア順にソートした行を戻すためにテキスト・ドメイン索引を使用せずにスループットを向上させています。かわりに、
CONTAINS
述語を満たすすべての行が索引から取り出された後で、Oracle Textによって行がソートされます。select /*+ FIRST_ROWS(10) DOMAIN_INDEX_NO_SORT */ pk, score(1), col from ctx_tab where contains(txt_col, 'test', 1) > 0 order by score(1) desc;
10.4 Oracle Textのコンポジット・ドメイン索引
Oracle Databaseの拡張性フレームワークのコンポジット・ドメイン索引(CDI)機能を使用すると、構造化された列をOracle Textで索引付けできます。したがって、テキストと1つ以上の構造化された条件の両方が、Oracle Textの単一の索引の行ソースによって満たされます。次のタイプの問合せのパフォーマンスが向上します。
-
SQL
WHERE
句内の、構造化された条件を持つOracle Text問合せ -
構造化された
ORDER
BY
条件を持つOracle Text問合せ -
前述の2つの問合せタイプの組合せ
連結されたBツリー索引やビットマップ索引と同様、FILTER
BY
列およびORDER
BY
列の数が増えるに従って、アプリケーションではデータ操作言語(DML)のパフォーマンスが低下します。SCORE
によるソートのプッシュダウンが応答時間の短縮のために最適化されている場合、構造化されたソートまたはSCORE
と構造化されたソートの組合せのプッシュダウンも同様に、スループットの向上ではなく応答時間の短縮のために最適化されます。ただし、DOMAIN_INDEX_SORT
ヒントまたはFIRST_ROWS
(n)
ヒントを使用してフェッチ中にCDIにソートを含めるよう強制した場合、ヒットリスト全体を表示するには問合せ応答時間が大幅にかかります。
10.5 CDIによるパフォーマンス・チューニング
FILTER BY
列をMDATA
にマップできるため、RANGE
およびLIKE
でサポートされている機能を制限することで、等価検索の問合せパフォーマンスを最適化できます。ただし、FILTER
BY
列に連続した値が含まれている場合や、カーディナリティが非常に高い場合には、FILTER
BY
列をMDATA
にマッピングすることはお薦めしません。このようなマッピングは、非常に時間がかかり、$I
表の範囲が限定され、$X
のパフォーマンスが低下する可能性があります。このような連続した列の一例として、DATE
スタンプを使用した場合があります。このような連続した列の場合は、SDATA
へのマッピングをお薦めします。
SORT
述語およびFILTER
BY
述語をCDIに含めるか含めないかには、次のヒントを使用します。
-
DOMAIN_INDEX_SORT:
問合せオプティマイザは、適用可能なソート基準を指定されたCDIにプッシュしようとします。 -
DOMAIN_INDEX_NO_SORT:
問合せオプティマイザは、適用可能なソート基準を指定されたCDIにプッシュしないようにします。 -
DOMAIN_INDEX_FILTER
(table name index name): 問合せオプティマイザは、適用可能なFILTER
BY
述語を指定されたCDIにプッシュしようとします。 -
DOMAIN_INDEX_NO_FILTER
(table name index name): 問合せオプティマイザは、適用可能なFILTER
BY
述語を指定されたCDIにプッシュしないようにします。
ノート:
domain_index_filter
ヒントは、問合せオプティマイザにCDIの使用を強制しません。かわりに、CBOがCDIの使用を選択している場合は、フィルタ述語も索引に含められます。問合せオプティマイザにCDI索引の選択を強制するには、さらにINDEX
ヒントも使用する必要があります。
例10-1 CDIヒントを使用したOracle Text問合せのパフォーマンス・チューニング
次の例では、books
表に対し、最適化された問合せを実行しています。
SELECT bookid, pub_date, source FROM (SELECT /*+ domain_index_sort domain_index_filter(books books_ctxcdi) */ bookid, pub_date, source FROM books WHERE CONTAINS(text, 'aaa',1)>0 AND bookid >= 80 ORDER BY PUB_DATE desc nulls last, SOURCE asc nulls last, score(1) desc) WHERE rownum < 20;
10.6 トレースを使用した索引および問合せのボトルネックの解決
Oracle Textには、索引付けおよび問合せにおけるボトルネックを特定するためのトレース機能が備わっています。
Oracle Textには、事前定義済のトレースのセットが用意されています。各トレースは一意の番号で識別されます。CTX_OUTPUT
には、この番号の記号が含まれます。
各トレースでは、特定の数量を測定します。たとえば、テキスト問合せ時に選択される$I
行の数などです。
トレースは累積カウンタです。そのため、使用方法は次のようになります。
-
ユーザーがトレースを使用可能にします。
-
ユーザーが複数の操作を実行します。Oracle Textではアクティビティを測定し、トレースの結果を累積します。
-
ユーザーがトレース値を取得します。これは、ステップ2で実行されたすべての操作の合計値となります。
-
ユーザーがトレースを0(ゼロ)に再設定します。
-
ユーザーがステップ2を繰り返します。
このため、たとえば、ステップ2でユーザーが2つの問合せを実行し、問合せ1で$I
から15行を選択し、問合せ2で$I
から17行を選択した場合、ステップ3ではトレースの値は32 (15 + 17)となります。
トレースは1つのセッションに関連付けられています。トレースは、1つのセッション内で発生した演算を測定できますが、反対に、複数のセッション間で測定を行うことはできません。
パラレル同期化または最適化の際、トレースが現在有効になっている場合にかぎり、トレース・プロファイルはスレーブ・セッションにコピーされます。各スレーブでは、独自のトレースを累積し、終了前にすべてのトレース値を暗黙的にスレーブ・ログ・ファイルに書き込みます。
関連項目:
10.7 パラレル問合せの使用
通常、パラレル問合せは意思決定支援システム(DSS)およびオンライン分析処理(OLAP)に最適です。また、これらは、大規模なデータ・コレクションと複数のCPUを備え、同時ユーザー数が少ない分析システムや、Oracle Real Application Clusters (Oracle RAC)ノードにも最適です。
Oracle Textでは、次のパラレル問合せがサポートされています。
10.7.1 ローカルのCONTEXT索引でのパラレル問合せ
パラレル問合せは、ローカルのCONTEXT
索引のパラレル処理を指します。索引の並列度と様々なシステム属性に基づいて、Oracleにより、索引処理のために起動されるパラレル問合せスレーブの数が決定されます。各パラレル問合せスレーブが、1つ以上の索引パーティションを処理します。このデフォルトの問合せ動作は、パラレルに作成されるローカル索引に適用されます。
ただし、同時ユーザー数が多く負荷の高いシステムで問合せが連続的に実行される場合は、通常上位N個のヒットが最初の数個のパーティションによって満たされるため、問合せのスループットはパラレル問合せによって一般に低下します。たとえば、ORDER
BY
パーティション・キー列を持つ典型的な上位N個のテキスト問合せがあるとします。
select * from ( select story_id from stories_tab where contains(...)>0 order by publication_date desc) where rownum <= 10;
これらのテキスト問合せでは通常、パラレル問合せを使用するとパフォーマンスが低下します。
ALTER INDEX
文を次のように使用して、パラレル索引の操作後にパラレル問合せを使用禁止にできます。
Alter index <text index name> NOPARALLEL; Alter index <text index name> PARALLEL 1;
また、次のように、パラレル問合せを使用可能にしたり、並列度を上げることもできます。
Alter index <text index name> parallel < parallel degree >;
10.7.2 Oracle RACノード間のパラレル問合せ
Oracle Real Application Clusters (Oracle RAC)は、問合せのスループットを向上するために有効な手段です。Oracle Textで問合せの負荷が軽く良好なパフォーマンスが得られる場合は、問合せの負荷が増えた場合、Oracle RACによる優れた拡張性を期待できます。
Oracle Textのパフォーマンスは、(ローカル・パーティション索引を使用して)テキスト・データとOracle Text索引を物理的にパーティション化し、各パーティションが個別のOracle RACノードで処理されるようにすると、さらに向上させることができます。この方法で、複数のノード間でのキャッシュ・コンテンツの重複を回避することにより、Oracle RAC Cache Fusionのメリットを最大限に活用できます。
Oracle 10gリリース1では、索引の作成時に、Oracle Textの各索引パーティションが個別のデータベース・ファイルに格納される必要があります。これにより、Oracle RACの再マスタリング機能を使用できるようになり、データベース・ファイルのアフィニティが適用されるため、各ノードは特定のデータベース・ファイル、つまり特定のOracle Text索引パーティションに集中します。
Oracle 10gリリース2およびそれ以降では、データベース・オブジェクト・レベルのアフィニティがサポートされています。これにより、索引オブジェクト($I
表および$R
表)の特定ノードへの割当てが大幅に容易になっています。
Oracle RACは問合せのスループットとパフォーマンスを向上させるソリューションを提供していますが、データの容量が増加しても常に同じパフォーマンス向上が見込めるわけではありません。パフォーマンスの向上を図るには、システム・グローバル領域(SGA)キャッシュに使用できるメモリー量を増やすか、データをパーティション化して、問合せですべての表パーティションをヒットしなくても、必要な問合せ結果セットを提供できるようにします。
10.8 ブロック操作による問合せのチューニング
複数の述語を持つ問合せを発行すると、実行計画でブロック操作が行われる場合があります。たとえば、次の複合問合せについて考えます。
select docid from mytab where contains(text, 'oracle', 1) > 0 AND colA > 5 AND colB > 1 AND colC > 3;
すべての述語が非選択的で、colA、colBおよびcolCがビットマップ索引を持つと想定します。Oracle DatabaseのCBOでは、次の実行計画を選択します。
TABLE ACCESS BY ROWIDS BITMAP CONVERSION TO ROWIDS BITMAP AND BITMAP INDEX COLA_BMX BITMAP INDEX COLB_BMX BITMAP INDEX COLC_BMX BITMAP CONVERSION FROM ROWIDS SORT ORDER BY DOMAIN INDEX MYINDEX
BITMAP
AND
はブロック操作であるため、Oracle Textでは、BITMAP
AND
操作を実行する前に、Oracle Textのドメイン索引から戻されたROWIDとスコアのペアを一時的に保存する必要があります。
Oracle Textでは、これらのROWIDとスコアのペアをメモリーに保存しようとします。ただし、結果セットのサイズがSORT_AREA_SIZE
初期化パラメータの値を超える場合は、Oracle Textにより、これらの結果がディスク上の一時セグメントに排出されます。
ディスクに結果を保存すると余分なオーバーヘッドが発生するため、次のようにSORT_AREA_SIZE
パラメータを増やすと、パフォーマンスが向上します。
alter session set SORT_AREA_SIZE = <new memory size in bytes>;
たとえば、バッファを約8MBに設定します。
alter session set SORT_AREA_SIZE = 8300000;
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値として格納されます。使用する表は、検索のタイプによって異なります。
-
機能的検索の場合、
$K
表であるDR$indexname$K
を使用します。この単純な索引構成表(IOT)には、DOCID/ROWIDのペアごとに行が含まれています。 -
索引付き検索の場合、
$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を行う場合は、このパラメータのサイズを増やす必要があります。
関連項目:
-
メモリー割当ての詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。
-
SORT_AREA_SIZE
パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。
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)およびオンライン分析処理(OLAP)に最適です。また、これらは、大規模なデータ・コレクションと複数のCPUを備え、同時ユーザー数が少ない分析システムや、Oracle Real Application Clusters (Oracle RAC)ノードにも最適です。
関連項目:
10.9.17 テーマには索引を付けた方がよいですか。
回答: テーマ情報にCONTEXT
索引で索引付けすると、時間がかかり、索引のサイズも大きくなります。ただし、テーマ索引を使用すると、ナレッジ・ベースが使用され、ABOUT
問合せの精度が上がります。アプリケーションで多くのABOUT
問合せを使用する場合は、索引に対してテーマ・コンポーネントを作成してみる価値はあります。ただし、索引付けの時間と記憶領域が余分に必要になります。
関連項目:
10.9.18 CTXCAT索引はどのような場合に使用すればよいですか。
回答: CTXCAT
索引は、テキストが小さなチャンク(わずか数行)になっており、特定の構造化基準(数値や日付など)に従って、検索で結果セットを制限またはソートする場合(あるいはその両方)に、最も効率的に機能します。
たとえば、オンラインのオークション・サイトについて考えます。各競売対象品目には、短い説明、現在の入札価格、オークションの開始日と終了日が含まれています。あるユーザーが、説明にantique cabinetが含まれ、かつ現在の入札価格が$500未満の全レコードを確認しようとしているとします。ユーザーが新しく提示される商品に特に興味がある場合は、結果をオークション開始日でソートする必要があります。
CONTEXT
索引に対するCONTAINS
構造化問合せの場合、この検索は常に効率的とはかぎりません。構造化句およびCONTAINS
句に応じて、応答時間が大きく異なる場合があります。これは、構造化句とCONTAINS
句の交差またはOracle Text問合せの順序付けが問合せ中に計算されるためです。
構造化情報をCTXCAT
索引内に含めると、検索条件にかかわらず、問合せ応答時間は常に最適な範囲内にとどまります。索引付け中にテキスト問合せと構造化問合せの間の相互作用が事前に計算されるため、問合せ応答時間は最適です。
10.9.19 CTXCAT索引が適さないのは、どのような場合ですか。
回答: 索引作成に要する時間と領域に違いがあります。CTXCAT
索引はCONTEXT
索引と比べて作成に時間がかかり、使用するディスク領域もかなり多くなります。ディスク領域に余裕がない場合は、CTXCAT
索引が適切かどうかを慎重に考慮してください。
問合せ演算子では、CATSEARCH
問合せでは問合せテンプレートを使用して、より豊富なCONTEXT
構文を使用できます。CATSEARCH
問合せ文法のみを使用する必要があるという古い制限はなくなりました。
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索引から受け入れ、それ以上のソートを実行しないように指示されます。
関連項目:
10.10 索引付けのパフォーマンスに関するFAQ(よくある質問)
この項では、索引付けのパフォーマンスに関してよくある質問と、それに対する回答を提供します。
10.10.1 索引付けにはどのくらいの時間が必要ですか。
回答: テキストの索引付けは、リソース集中型の処理です。索引付けの速度はハードウェアの性能に依存します。索引付けの速度はCPUおよびI/O容量により異なります。元のデータの読込みや索引エントリの書込みに十分なI/O容量がある場合、CPUが制限要素となります。
Intel x86 (Core 2アーキテクチャ、2.5GHz) CPUを使用したテストでは、Oracle Textでは1日当たりCPUコアごとに約100GBのテキストを索引付けできました。この速度になると、CPUクロック速度が増し、CPUアーキテクチャがさらに効率的になることが予想されます。
ドキュメント形式、データの場所、ユーザー定義データストアのコール、フィルタ、レクサーなどのその他の要因も、索引付けの速度に影響します。
10.10.2 どの索引メモリー設定を使用すればよいですか。
回答: 索引メモリーは、DEFAULT_INDEX_MEMORY
およびMAX_INDEX_MEMORY
システム・パラメータを使用して設定できます。また、CREATE INDEX
のパラメータ文字列にmemory
パラメータを指定して、索引メモリーを実行時に設定することもできます。
DEFAULT_INDEX_MEMORY
値は、ページングが発生しない範囲で、できるだけ高く設定するようにします。
SORT_AREA_SIZE
システム・パラメータを増やして、索引付けのパフォーマンスを向上させることもできます。
索引メモリーの設定を大きくすることをお薦めします。数百MBまで設定を大きくすると、索引付けの速度が上がり、最終的な索引の断片化が減少します。ただし、索引メモリー設定を高くしすぎると、メモリーのページングが発生して索引付けの速度が低下します。
索引のパラレル作成では、各プロセスがそれぞれ索引付け用のメモリーを必要とします。巨大な表を扱う場合には、索引作成時と検索時とで、システム・グローバル領域(SGA)のチューニング方法を変えます。問合せでは、SGAのブロック・バッファ・キャッシュにできるだけ多くの情報をキャッシュするようにします。このため、ブロック・バッファ・キャッシュには大量のメモリーを割り当てる必要があります。このアプローチは索引付けには影響を与えないため、索引付け中は、SGAのサイズを減らして、索引メモリー設定を大きくする方が賢明です。
SGAのサイズはOracle Database初期化ファイルで設定します。
関連項目:
-
メモリー割当ての詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。
-
SORT_AREA_SIZE
パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。
10.10.3 索引付けにはどの程度のディスク・オーバーヘッドが必要ですか。
回答: オーバーヘッド(索引表に必要な領域の量)は、元のテキスト量の50%から200%までの範囲で様々です。一般に、テキストの総量が多いほどオーバーヘッドは小さくなりますが、小さなレコードが多数ある方が、大きなレコードが少数あるよりもオーバーヘッドの消費が大きくなります。また、電子メールや討論記録のような未処理のデータにはスペルミスや略語などのワードが数多く含まれている可能性が高いため、クリーンなデータ(出版されたテキストなど)の方が未処理のデータよりも必要なオーバーヘッドが小さくなります。
テキストのみの索引は、テキストとテーマを組み合せた索引よりも小さくなります。プリフィックス索引およびサブストリング索引では、索引がかなり大きくなります。
10.10.4 データの形式は索引付けにどのように影響しますか。
回答: Microsoft Wordファイルのように形式設定されたドキュメントの場合は、ドキュメントに含まれる実際のテキストに比べてサイズが大きくなる傾向があるため、記憶域オーバーヘッドはかなり低くなります。したがって、1GBのWordドキュメントに必要な索引領域が50MBのみであるのに対し、1GBのプレーン・テキストに必要な索引領域は500MBになることがあります。
索引付けに要する時間については、これほど単純ではありません。索引付け対象のテキスト量が減れば明らかな影響は出ますが、索引付けに要する時間を見積るためには、AUTO_FILTER
フィルタまたはその他のユーザー定義フィルタを使用してドキュメントをフィルタ処理する時間を相殺することが必要になります。
10.10.5 パラレル索引付けにより、パフォーマンスは向上しますか。
回答: データが大量にあり、CPUも複数ある場合は、パラレル索引付けにより、索引付けのパフォーマンスが向上します。
リソースに応じて最大3つの索引付けプロセスで索引を作成するには、PARALLEL
キーワードを使用します。
CREATE INDEX index_name ON table_name (column_name) INDEXTYPE IS ctxsys.context PARAMETERS ('...') PARALLEL 3;
また、パラレル索引付けを使用して、パーティション表のローカル・パーティション索引を作成することもできます。ただし、CPUが複数あるときのみ、索引付けのパフォーマンスは向上します。
ノート:
ローカル・パーティション索引を作成するのにPARALLEL
を使用すると、パラレル問合せが有効になります。(非パーティション索引をパラレルに作成しても、問合せはパラレルに処理されません。)
パラレル問合せは、特に負荷の大きいシステムに対して実行すると、問合せのスループットが低下します。このため、パラレル索引作成後はパラレル問合せを使用禁止にすることをお薦めします。この場合は、ALTER INDEX NOPARALLEL.
を使用します
10.10.6 ローカル・パーティション索引を作成する場合、索引のパフォーマンスを改善するにはどうすればよいですか。
回答: CPUが複数あるときは、ローカル索引をパラレルで作成することで索引付けのパフォーマンスを改善できます。
ローカル・パーティション索引をパラレルに作成するには、次の方法があります。
-
CREATE INDEX
文でPARALLEL
句とLOCAL
句を使用します。この場合、最大並列度はパーティション数に制限されます。 -
UNUSABLEの索引を作成してから、
DBMS_PCLXUTIL.BUILD_PART_INDEX
ユーティリティを実行します。この方法により、特にパーティションより多くのCPUを使用している場合に、並列性が高くなります。
2つ目の方法の例を次に示します。元表には3つのパーティションがあります。まず、使用禁止のローカル・パーティション索引を作成してから、DBMS_PCLUTIL.BUILD_PART_INDEX
を実行すると、3つのパーティションがパラレルに作成されます(パーティション間並列性)。各パーティション内の索引は、並列度2でパラレルに作成されます(パーティション内並列性)。
create index tdrbip02bx on tdrbip02b(text) indextype is ctxsys.context local (partition tdrbip02bx1, partition tdrbip02bx2, partition tdrbip02bx3) unusable; exec dbms_pclxutil.build_part_index(3,2,'TDRBIP02B','TDRBIP02BX',TRUE);
10.11 索引の更新に関するFAQ(よくある質問)
この項では、索引の更新と関連するパフォーマンスの問題に関してよくある質問と、それに対する回答を提供します。
10.11.1 新規または更新されたレコードの索引付けは、どのくらいの頻度で行う必要がありますか。
回答: CTX_DDL.SYNC_INDEX
を使用して再索引付けを実行する頻度が低いと、索引の断片化が少なくなり、索引の最適化を実行する頻度も低く抑えることができます。
ただし、データが次第に古くなるため、ユーザーにとっては不便になる可能性があります。
ほとんどのシステムでは、毎日の夜間の索引付けで対応可能です。この場合、作成されてから1日未満のデータは検索できないということになります。毎時、10分ごとまたは5分ごとに更新を行うシステムもあります。
関連項目:
10.11.2 索引の断片化は、どのようにするとわかりますか。
回答: 最善の方法は、いくつかの問合せに要する時間を測定してから、索引の最適化を実行し、その後で同じ問合せの時間を再度測定することです(SGAをクリアするために、その都度データベースを再起動する必要があります)。問合せの速度が大幅に上がっている場合は、最適化が有効であったことを示しています。そうでない場合は、次回は待機時間が長くなる可能性があります。
索引の断片化の分析には、CTX_REPORT.INDEX_STATS
を使用することもできます。
関連項目:
-
「索引の最適化」