25 インメモリーJSONデータ

問合せのパフォーマンスを向上させるために、JSONデータの列をインメモリー列ストア(IM列ストア)に格納できます。

トピック:

25.1 インメモリーJSONデータの概要

JSONデータの列が格納された表をインメモリー列ストア(IM列ストア)に移動すると、コストがかかる式の結果をキャッシュすることで、これらの式を共有する問合せのパフォーマンスを向上させることができます。これは、小さいJSON文書を大量にスキャンする分析問合せに特に便利です。

IM列ストアは、32,767バイトより小さいJSON文書に対してのみサポートされます。様々な文書サイズが混在する場合、32,767バイトより大きい文書はインメモリーの最適化が行われずに処理されます。よりよいパフォーマンスを得るために、32,767バイトを超える文書を小さい文書に分割することを検討します。

IM列ストアは任意に入力できるSGAプールです。ここには、迅速にスキャンできるように最適化された特殊な列形式で、表のコピーおよびパーティションが格納されています。IM列ストアはデータベース・バッファ・キャッシュの行ベース記憶域を補完します。IM列ストアとバッファ・キャッシュの両方に同じオブジェクトをロードする必要はありません。2つのキャッシュは、トランザクションの面で一定に保たれます。データベースは、バッファ・キャッシュにオンライン・トランザクション処理(OLTP)問合せ(主キーの検索など)を、IM列ストアに分析およびレポートの問合せを透過的に送信します。

インメモリーのJSONデータを使用することは、SQL/JSONパス・アクセスのパフォーマンス強化と考えられます。SQL/JSONファンクションjson_tablejson_queryおよびjson_valueと、SQL条件json_existsは、すべてSQL/JSONパス引数を受け入れ、JSONデータをIM列ストアにロードすることでメリットを得ることができます。(SQL/JSONファンクションjson_textcontainsを使用した全文検索では、IM列ストアを使用するメリットはありません。)JSON文書がメモリーにロードされると、この文書に対して以降に行われるパスベースの操作ではインメモリーの表現が使用されます。これにより、ディスク上で行われる読取りおよび解析に関連するオーバーヘッドが不要になります。

問い合せされたJSONデータがIM列ストアに移入され、そのデータに適用できる関数ベースの索引がある場合、オプティマイザは索引を使用するか、インメモリーのデータをスキャンするかを選択します。一般的に、索引を調べた結果の文書がほとんどない場合には、オプティマイザによって関数索引が選ばれます。これは、実際には、オプティマイザが非常に選択的な問合せやDML文で関数索引を選ぶ可能性があることを意味します。

反対に、索引を調べた結果の文書が多くなる場合、オプティマイザは、関数ベースの索引の式を仮想列の式としてスキャンすることによるインメモリー・データのスキャンを選択する可能性があります。

非定型の問合せ(つまり、特定のSQL/JSONパス式を対象とするために頻繁には使用されない問合せ)では、データのスキャンを迅速に行えるため、JSONデータをIM列ストアに移入することで得られる一般的なメリットを受けられます。頻繁に使用する問合せがいくつかある場合は、次のようにしてそれらのパフォーマンスをさらに向上させることができます。

  • JSONデータの列から、スカラー値(配列内のものではない)を投影する仮想列を作成し、それらの仮想列をIM列ストアにロードする。

  • 頻繁に問い合せられるjson_table式にマテリアライズド・ビューを作成し、そのビューをIM列ストアにロードする。

ただし、関数json_valueを使用してスカラー値を投影する関数ベースの索引がある場合は、それを投影する仮想列を明示的に作成する必要はありません。前述したように、この場合は、関数ベースの索引の式がIM列ストアに仮想列として自動的にロードされます。オプティマイザは、推定されるコストに基づいて、関数ベースの索引を通常の方法でスキャンするか、索引式を仮想列の式としてスキャンするかを選択できます。

注意:

  • マテリアライズド・ビューではなく、仮想列を利用する利点は、索引を構築できることと、オプティマイザ用に統計情報を取得できることです。

  • 仮想列には、一般的な列と同様に、1つの特定の表に対して1000列の制限があります。

JSONデータをインメモリーで使用するための前提条件

JSONデータでIM列ストアのメリットを利用するためには、次のすべての項目を満たす必要があります。

  • データベースの互換性が12.2.0.0以上である。

  • Oracleインスタンスのスタートアップ構成ファイルで、max_string_sizeの値が'extended'に設定されている必要がある。

  • IM列ストアに対して、十分なSGAメモリーが構成されている必要がある。

  • JSON列を格納する表領域、表またはマテリアライズド・ビューが、CREATEまたはALTERの文でキーワードINMEMORYを使用してIM列ストアに移入できるように、DBAで指定されている。

  • 次のように初期化パラメータが設定されている。

    • IMMEMORY_EXPRESSIONS_USAGEが、STATIC_ONLYまたはENABLEになっている。

      ENABLEをPL/SQLプロシージャDBMS_INMEMORY.ime_capture_expressionsと組み合せて使用すると、動的な式のインメモリー・マテリアライズが可能になります。

    • IMMEMORY_VIRTUAL_COLUMNSENABLEになっている。これは、IM列ストアがすべての仮想列を移入することを意味します。(デフォルト値はMANUAL。)

  • JSONデータを格納する列それぞれに、is jsonチェック制約が含まれる必要がある。(つまり、データがJSONデータであることがわかっている必要がある。)

各初期化パラメータの値は、SHOW PARAMETERコマンドを使用して確認できます。(データベース・ユーザーSYSまたはそれと同等のユーザーとしてログインしている必要があります。)次に例を示します。

SHOW PARAMETER INMEMORY_VIRTUAL_COLUMNS

25.2 JSONデータのインメモリー列ストアへの移入

ALTER TABLE INMEMORYを使用して、JSONデータの列が格納された表をインメモリー列ストア(IM列ストア)に移入すると、コストがかかる式の評価結果をキャッシュすることで、これらの式を共有する問合せのパフォーマンスを向上させることができます。

IM列ストアは任意に入力できるSGAプールです。ここには、迅速にスキャンできるように最適化された特殊な列形式で、表のコピーおよびパーティションが格納されています。IM列ストアはデータベース・バッファ・キャッシュの行ベース記憶域を補完します。(バッファ・キャッシュは置き換えられませんが、IM列ストアとバッファ・キャッシュの両方に同じオブジェクトをロードする必要はありません。2つのキャッシュは、トランザクションの面で一定に保たれます。)

特定のJSON列(つまり、is jsonチェック制約が含まれる列)が格納された表をINMEMORYとして設定することで、その表がIM列ストアに移入されるように指定します。例25-1に、これを示します。

IM列ストアは、32,767バイトより小さい文書の問合せに使用されます。これより大きな文書の問合せでは、IM列ストアを利用するメリットがありません。

注意:

IM列ストアに移入する表のJSON列が、12.2以降の互換性設定がないデータベースを使用して作成された場合、またはmax_string_sizeextendedに設定されていなかった場合(Oracle Database 12c リリース2 (12.2.0.1)より前の場合などに該当)は、まず、スクリプトrdbms/admin/utlimcjson.sqlを実行する必要があります。これは、JSON列が含まれる既存の表すべてで、リリース12.2.0.1で追加されたインメモリーのJSON処理を利用できるように準備します。インメモリー列ストアで使用するための、JSONデータが格納された表のアップグレードを参照してください。

JSON列が含まれる表をINMEMORYにすると、各JSON列についてインメモリーの仮想列がその表に追加されます。対応する仮想列は、特定のJSON列の問合せに使用されます。仮想列には、対応するJSON列と同じJSONデータが含まれますが、その形式はOracleのバイナリ形式OSONになります。

例25-1 JSONデータのIM列ストアへの移入

SELECT COUNT(1) FROM j_purchaseorder
  WHERE json_exists(po_document,
                    '$.ShippingInstructions?(@.Address.zipCode == 99236)');

-- The execution plan shows: TABLE ACCESS FULL


-- Specify table as INMEMORY, with default PRIORITY setting of NONE,
-- so it is populated only when a full scan is triggered.

ALTER TABLE j_purchaseorder INMEMORY;

-- Query the table again, to populate it into the IM column store.
SELECT COUNT(1) FROM j_purchaseorder
  WHERE json_exists(po_document,
                    '$.ShippingInstructions?(@.Address.zipCode == 99236)');

-- The execution plan for the query now shows: TABLE ACCESS INMEMORY FULL

25.3 インメモリー列ストアで使用するための、JSONデータが格納された表のアップグレード

12.2以降の互換性設定のないデータベースmax_string_size = extendedが設定されなかったデータベースを使用して作成されたJSON列が含まれる表は、インメモリー列ストア(IM列ストア)に移入する前にアップグレードする必要があります。これを行うには、スクリプトrdbms/admin/utlimcjson.sqlを実行します。

スクリプトrdbms/admin/utlimcjson.sqlを実行すると、JSON列が含まれるすべての既存の表が、IM列ストアに移入されるようにアップグレードされます。これを使用するには、次の項目のすべてを満たす必要があります。

  • データベース・パラメータcompatible12.2.0.0以上に設定する必要がある。

  • データベース・パラメータmax_string_sizeextendedに設定されている必要がある。

  • アップグレードするJSON列に、is jsonチェック制約が定義されている必要がある。