3.16 インメモリー全文検索とJSON全文検索

全文ドキュメントまたはJSONドキュメントを格納する基の列がインメモリー全文検索に対応している場合、CONTAINS()およびJSON_TEXTCONTAINS()を使用する問合せをSQL述語で評価できます。

通常、テキスト列に対して全文(キーワード)検索を使用するには、その列にOracle Text索引を作成する必要があります。JSONデータについては、JSON検索索引を作成します。Oracle Databaseリリース21c以降では、索引を作成するかわりに、インメモリー列形式を使用して、列をメモリーにロードできます。これには索引は必要ありませんが、インメモリー手法を使用してテキストを高速でスキャンできます。これは、テキスト検索と構造化検索を結合した問合せを他のインメモリー列で実行する場合に特に便利です。

INMEMORY TEXT句を使用して、表の作成時にメモリーにロードする必要がある列を宣言する必要があります。これらの列は、Oracle TextまたはJSON検索索引で使用されるものと同じCONTAINS()およびJSON_TEXTCONTAINS()関数を使用して検索できますが、使用できる問合せ演算子のタイプには制限があります。したがって、インメモリーは、Oracle TextまたはJSON検索索引にかわるものではなく、制限が問題であると見なされない場合に必要に応じて使用できる代替手段です。

Oracle Text索引がある列にINMEMORY TEXT句を使用することもできます。このような状況の場合、オプティマイザによって問合せを実行するためのOracle Text索引が選択されます。列にOracle Text索引がある場合は、その問合せで常にOracle Text索引が使用されます。Oracle Text索引がない場合は、オプティマイザによって、その表がインメモリーとしてマークされているかどうかがチェックされます。表がインメモリーとしてマークされている場合は、その問合せにインメモリー評価が使用されます。Oracle Text索引がなく、表がインメモリーとしてマークされていない場合は、「DRG-10599: 列は索引付けされていません」というエラーが戻されます。

CONTEXT索引とは異なり、INMEMORY TEXT句は、LOB (ラージ・オブジェクト)やLONG列に対して間接データストア・タイプ(NETWORK_DATASTOREおよびDIRECTORY_DATASTORE)とともに使用できます。

インメモリー・テキスト列を指定する方法の詳細は、『Oracle Database In-Memoryガイド』を参照してください。

サポートされているデータ型

インメモリー全文検索では、次のデータ型がサポートされています。
  • CHAR

  • VARCHAR2

  • CLOB

  • BLOB

  • JSON

JSON列とテキスト列の両方で、CTX_DDL.CREATE_POLICYプロシージャで作成されたカスタム索引付けポリシーがサポートされています。列のデータ型がJSONの場合は、その列で次のいずれかを使用するときに、その列のインメモリー全文バージョンで、JSON_TEXTCONTAINS()を使用したパス対応検索が可能です。
  • デフォルト・ポリシー

  • JSON_ENABLED属性がTRUEに設定されたPATH_SECTION_GROUPを使用するカスタム・ポリシー

使用上のノート

INMEMORY TEXT句を使用して、インメモリー全文検索列を指定します。CREATE TABLE文とALTER TABLE文の両方で、INMEMORY TEXT句がサポートされています。PRIORITY副句を使用して、オブジェクトの移入順序を制御できます。デフォルトの優先度はNONEです。MEMCOMPRESS副句は、INMEMORY TEXTでは無効です。

次のいずれかの形式を使用して、CREATE TABLE文またはALTER TABLE文でINMEMORY TEXT句を指定します。
  • INMEMORY TEXT (col1, col2, …)

  • INMEMORY TEXT (col1 USING policy1, col2 USING policy2, …)

DML操作のバッチの後または問合せの実行前に、インメモリー再移入操作を実行することをお薦めします。オブジェクトの即時再移入を強制的に実施するDBMS_INMEMORY.REPOPULATEプロシージャを使用できます。Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンスを参照してください。

INMEMORY TEXT句を使用する場合は、次のデータベース初期化パラメータを設定する必要があります:
  • MAX_STRING_SIZE: このパラメータにより、SQL内のVARCHAR2NVARCHAR2およびRAWデータ型の最大サイズを制御します。MAX_STRING_SIZEEXTENDEDに設定する必要があります。この設定では、バイト上限が32767に上がります。これには、データベースの停止またはアップグレードが必要です。

  • INMEMORY_EXPRESSIONS_USAGE: このパラメータにより、データベースで移入されるIM式のタイプを制御します。INMEMORY_EXPRESSIONS_USAGEDISABLE以外の値に設定します:
    • ENABLE (デフォルト): 静的IM式と動的IM式の両方を有効にします

    • STATIC_ONLY: 静的IM式のみを有効にします

  • INMEMORY_VIRTUAL_COLUMNS: このパラメータにより、どのユーザー定義仮想列をIM仮想列として格納するかを制御します。INMEMORY_VIRTUAL_COLUMNSENABLEに設定します。これはデフォルト設定です。

制限事項

例3-1 インメモリー全文検索の使用方法

次の例では、CONTAINS演算子を使用してインメモリー全文検索対応の列から問い合せる方法を示します。また、テキスト検索のカスタム・ポリシーを作成し、列に適用する方法も示します。

メモリーにロードされるtext_docsという名前の表を作成し、docという名前のインメモリー全文検索列を移入します。

CREATE TABLE text_docs(id NUMBER,  docCreationTime DATE, doc CLOB) INMEMORY INMEMORY TEXT(doc);

条件でCONTAINS演算子を使用して問い合せます。

SELECT id FROM text_docs WHERE docCreationTime >  to_date('2014-01-01', 'YYYY-MM-DD') 
AND CONTAINS(doc, 'in memory text processing');

テキスト検索のカスタム・ポリシーを作成し、doc列に適用することもできます。

EXEC CTX_DDL.CREATE_POLICY('first_policy');
ALTER TABLE text_docs INMEMORY TEXT (doc USING 'first_policy');

既存のカスタム・ポリシーを置き換えるには、NO INMEMORY TEXT句を使用してインメモリー全文検索を無効にした後、INMEMORY TEXT句を使用してインメモリー全文検索を有効にします。

EXEC CTX_DDL.CREATE_POLICY('second_policy');
ALTER TABLE text_docs NO INMEMORY TEXT(doc);
ALTER TABLE text_docs INMEMORY TEXT (doc USING 'second_policy');

例3-2 JSONインメモリー全文検索の使用方法

次の例では、JSON_TEXTCONTAINS演算子を使用してインメモリー全文検索対応の列から問い合せる方法を示します。

メモリーにロードされるjson_docsという名前の表を作成し、docという名前のインメモリー全文検索列を移入します。

CREATE TABLE json_docs(id NUMBER,  docCreationTime DATE, doc JSON) INMEMORY INMEMORY TEXT(doc);

条件でJSON_TEXTCONTAINS演算子を使用して問い合せます。

SELECT id FROM json_docs WHERE docCreationTime >  to_date('2014-01-01', 'YYYY-MM-DD') 
AND JSON_TEXTCONTAINS(doc, '$.abstract', 'in memory text processing');

例3-3 全文検索でのインメモリー移入の優先度の設定

次の例では、PRIORITY副句を使用してデータ移入の優先度レベルを設定する方法を示します。

メモリーにロードされるprioritized_docsという名前の表を作成し、PRIORITY副句を使用して優先度レベルを設定します。

CREATE TABLE prioritized_docs(id NUMBER,  docCreationTime DATE, doc CLOB, json_doc CHECK(json_doc IS json)) 
INMEMORY PRIORITY CRITICAL INMEMORY TEXT(doc, json_doc);