5 インメモリー式による問合せの最適化

IM列ストアとの関連においては、は、1つ以上の値、演算子、および値を解決するSQLまたはPL/SQL関数(DETERMINISTICのみ)の組合せです。

式統計ストア(ESS)では、頻繁に評価される(ホットな)式の結果が自動的に追跡されます。DBMS_INMEMORY_ADMINパッケージを使用して、ホットな式を取得し、それらを非表示の仮想列として移入するか、それらの一部またはすべてを削除できます。

この章のトピックは、次のとおりです:

5.1 IM式について

デフォルトでは、DBMS_INMEMORY_ADMIN.IME_CAPTURE_EXPRESSIONSプロシージャは、インメモリー式(IM式)と呼ばれる、ホットな式を特定および移入します。

IM式は、非表示の仮想列としてマテリアライズされますが、非仮想列と同じ方法でアクセスされます。マテリアライズされた式を格納するために、IM列ストアでは、固定幅ベクター、および固定幅コードでのディクショナリ・エンコーディングなど、特別な圧縮形式が使用されます。

Oracle Databaseにより、IM列ストアへの移入の候補となる式が自動的に特定されます。DBA_IM_EXPRESSIONS.COLUMN_NAMEでは、IM式の列には接頭辞SYS_IMEがあります。SYS_IME列を直接作成することはできません。たとえば、weekly_salおよびann_compという別名が付けられた2つの式を指定する、次のような問合せを考察します。

SELECT employee_id, last_name, salary, commission_pct,
       ROUND(salary*12/52,2) as "weekly_sal",
       12*(salary*NVL(commission_pct,0)+salary) as "ann_comp"
FROM   employees
ORDER BY ann_comp;

ROUND(salary*12/52,2)および12*(salary*NVL(commission_pct,0)+salary)の計算式は、計算が集中的に行われて頻繁にアクセスされ、それにより、それらは非表示のIM式列の候補になります。

DBMS_INMEMORY_ADMINパッケージは、IM式を管理するための主要インタフェースです。

  • 次回の再移入中にデータベースでIM式を特定してそれらがそれぞれの表に追加されるようにするには、IME_CAPTURE_EXPRESSIONSを使用します。

  • IM式の即時移入を強制的に実行するには、IME_POPULATE_EXPRESSIONSを使用します。

  • SYS_IME列を削除するには、DBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONSまたはDBMS_INMEMORY.IME_DROP_EXPRESSIONSを使用します。

この項では、次の項目について説明します。

関連項目:

5.1.1 IM式の目的

IM式により、計算が集中的に行われる式を事前計算することで、データ・セットが大きい問合せが高速化されます。IM式は、頻繁に実行される表結合、投影および述語評価に特に役立ちます。

IM式の主な利点は、次のとおりです。

  • 問合せで、式を毎回再計算する必要がありません。IM列ストアが式結果を移入しないと、データベースでは行ごとに計算が必要になり、これはリソースが集中的に消費されます。データベースで、移入中にCPUのオーバーヘッドが発生します。

  • IM式のマテリアライズによって、SIMDベクター処理やIMCUプルーニングなどのパフォーマンス強化機能をデータベースで利用できるようになります。

  • ユーザーではなくデータベースにより、どの式が最もアクティブかが追跡されます。

IM式とマテリアライズド・ビューは、式の評価の繰返しをどのように回避するかという同じ問題に対応しています。ただし、IM式にはマテリアライズド・ビューを上回る利点があります。

  • IM式では、永続的に格納されるわけではないデータを取得できます。

    たとえば、IM列ストアでは、問合せ内の式に基づいて、内部計算を自動的にキャッシュできます。

  • 効率的に使用するために、マテリアライズド・ビューには問合せでリストされるすべての列が含まれるか、問合せがビューおよびベース表を結合する必要があります。対照的に、IM式が含まれる問合せはいずれも利点を享受できます。

  • ユーザーが作成したオブジェクトであるマテリアライズド・ビューとは異なり、データベースでは、IM式は自動的に特定および作成されます。

関連項目:

5.1.2 IM式はどのように機能するか

式をIM式の候補として特定するために、データベースでは、ESSに問い合せます。オプティマイザでは、ESSを使用して、表に対する式評価についての統計が保持されます。

この項では、次の項目について説明します。

5.1.2.1 IM式のインフラストラクチャ

IM式のインフラストラクチャは、IM式の結果、IM仮想列、およびIM列ストア内のその他の役立つ内部計算を計算および移入する役割を担います。これらの最適化は、主に分析問合せに役立ちます。

移入された結果には、投影、スキャンまたは結合式で使用される列上の関数評価が含まれる可能性があります。IM列ストアでは、問合せ評価中に、SQLランタイム・エンジンによって評価される式に基づいて、内部計算を自動的にキャッシュできます。

仮想列

IM式の移入の他に、IM列ストアでは、インメモリー仮想列を移入できます。基礎となるメカニズムは同じです。IM式は仮想列です。ただし、IM仮想列がユーザーによって作成され公開されるのに対して、IM式はデータベースによって作成され非表示にされます。

静的式: バイナリJSON列

IM式のインフラストラクチャでは、動的式(IM式および仮想列)と静的式の両方がサポートされています。

Oracle Database 12cリリース2 (12.2)以降、IM列ストアでは、バイナリJSON形式のOSONがサポートされています。これは、行指向のJSONテキスト・ストレージよりもパフォーマンスに優れています。問合せでは、実際のJSONデータにアクセスしますが、アクセスの高速化のために、最適化された仮想列を使用します。

データベースでは、IM式のインフラストラクチャを使用して、JSONテキスト列の効率的なバイナリ表現が仮想列としてロードされます。MAX_STRING_SIZE初期化パラメータが、VARCHAR2データ型のEXTENDEDに設定されている場合は、IM列ストアに32KBまでのOSON仮想列を格納できます。

Oracle Databaseでは、JSON_TABLEJSON_VALUEおよびJSON_EXISTSという複数のJSON関数がサポートされています。INMEMORY_EXPRESSIONS_USAGE初期化パラメータは、動的式と静的式の両方の挙動を制御します。

関連項目:

5.1.2.2 IM式の取得

IME_CAPTURE_EXPRESSIONSプロシージャを呼び出したときは必ず、データベースで、ESSに問合せが行われ、指定された時間範囲で最も頻繁にアクセスされている(最もホットな)式が20個特定されます。

時間範囲は、過去24時間またはデータベース作成以降のどちらかです。データベースでは、IM列ストアに少なくとも一部分が移入されている表の式のみが考慮されます。

データベースにより、最もホットな20個の式がそれぞれの表に非表示のSYS_IME仮想列として追加され、デフォルトのINMEMORY列圧縮句が適用されます。前の呼出し時に追加されたSYS_IME列が最新の式リスト内になくなると、データベースにより、それらの属性がNO INMEMORYに変更されます。

属性がINMEMORYかどうかに関係なく、表のSYS_IME列の最大数は50個です。表の式が上限の50個に達した後は、データベースにより、新しいSYS_IME列は追加されません。新しい式を許可するには、SYS_IME列をDBMS_INMEMORY.IME_DROP_EXPRESSIONSまたはDBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONSプロシージャを使用して削除する必要があります。

SYS_IME仮想列およびユーザー定義の仮想列のどちらも、表での列の上限である1000個に数えられます。たとえば、表に980個の非仮想(ディスク上)列が含まれる場合は、20個の仮想列のみを追加できます。

5.1.2.3 ESSはどのように機能するか

ESSは、式評価についての統計を格納するためにオプティマイザによって保持されるリポジトリです。

表ごとに、ESSで実行頻度や評価コストなどの式統計が保持されます。述語の評価時は、Oracle Databaseにより、式の評価回数および動的コストに関して実行時フィードバックが追跡および提供されます。ESS統計に基づいて、データベースで、特定の式がIM式であれば問合せのパフォーマンスが向上すると判断される場合があります。

注意:

特定の表のESSにキャッシュされた式には、この表の列のみが含まれます。このルールは、Oracle Databaseで決定性のPL/SQL関数がIM式の候補として特定された場合は、特に重要となります。

図5-2 ESSとIM式

この図で、ESSではemployees表で一般的に使用される2つの式、ROUND(salary*12/52,2)および12*(salary*NVL(commission_pct,0)+salary)が決定されました。データベースによってemployeesがIM列ストアに移入されると、2つのIMCUに列データが格納されます。各IMCUはそのIMEUのみと関連付けられ、これには、そのIMCU内の行に対して一般的に使用される2つの式の導出された値が含まれています。

図5-2の説明が続きます
「図5-2 ESSとIM式」の説明

すべての式がIM式の候補であるわけではありません。データベースでは、頻繫にアクセスされる式のみが考慮されます。IM式は非表示の仮想列として実装されるため、仮想列の制限事項を満たしている必要もあります。

IM列ストアはESSのクライアントですが、ESSはDatabase In-Memoryの機能から独立しています。オプティマイザ自体など、他のクライアントもESS統計を使用できます。

関連項目:

5.1.2.4 データベースではどのようにIM式が移入されるか

インメモリー・コーディネータ・プロセス(IMCO)の指示に従い、領域管理ワーカー・プロセス(Wnnn)で、IM式がIMEUに自動的にロードされます。

データベースで、ユーザー定義またはIM式のどちらの仮想列を移入するかに関する情報とともに、すべてのインメモリー圧縮単位(IMCU)の移入または再移入タスクが増大されます。決定は、INMEMORY_EXPRESSION_USAGEおよびINMEMORY_VIRTUAL_COLUMNS初期化パラメータの設定によって異なります。

注意:

DBMS_INMEMORY.IME_CAPTURE_EXPRESSIONSプロシージャは、自動検出した式を非表示の仮想列として追加します。

Wnnnプロセスにより、IMCUが作成されます。IMEUを作成するために、それらのプロセスで、次のような手順がさらに実行されます。

  1. 式値を作成します

  2. 値を列形式に変換し、それらをインメモリー式単位(IMEU)に圧縮します

  3. 各IMEUをその関連するIMCUにリンクさせます

注意:

IMEUに格納する式の数が増加すると、ワーカー・プロセスで、式値を計算するために少し多くのCPUが使用される場合があります。このオーバーヘッドにより、移入時間が長くなることがあります。

5.1.2.5 IMEUはどのようにIMCUに関連するか

どの行についても、物理的な列はIMCU内に存在し、仮想列は関連するIMEU内に存在します。IMEUは、IMCUと同様に、読取り専用であり、列となります。

IMEUは、特定のINMEMORYセグメントのために作成されたIMCUの論理拡張であるため、デフォルトでは、INMEMORY句、およびDISTRIBUTEおよびDUPLICATEなどのOracle Real Applications Cluster (Oracle RAC)プロパティを継承します。IMEUは、1つのIMCUのみと関連付けられます。データベースでは、追加および削除が容易になるよう、IMEUは別個の構造として管理されます。

注意:

IMEUには、ユーザーが作成したIM仮想列も含まれます。

ソース・データが変更された場合は、データベースにより、再移入中に、IM式で得られたデータが変更されます。たとえば、トランザクションで表内の100個の給与値が更新された場合は、領域管理ワーカー・プロセス(Wnnn)により、変更されたこれら100個の値から導出されるすべてのIM式値が自動的に更新されます。データベースでは、最初にすべてのIMCUを再移入してからすべてのIMEUを再移入するのではなく、IMCUおよびその関連するIMEUが一緒に再移入されます。IMEUは、IMCUの再移入中も問合せに使用できます。

5.1.3 IM式のユーザー・インタフェース

DBMS_INMEMORY_ADMINパッケージ、DBMS_INMEMORYパッケージおよびINMEMORY_EXPRESSIONS_USAGE初期化パラメータは、IM式の挙動を制御します。

この項では、次の項目について説明します。

5.1.3.1 INMEMORY_EXPRESSIONS_USAGE

INMEMORY_EXPRESSIONS_USAGE初期化パラメータは、どのタイプのIM式を移入するかを決定します。INMEMORY_VIRTUAL_COLUMNS初期化パラメータは、通常の(非表示ではない)仮想列の移入を制御します。

IM列ストアが有効になっている(INMEMORY_SIZEがゼロ以外)場合、INMEMORY_EXPRESSIONS_USAGEは、データベースで移入されるIM式のタイプを制御します。INMEMORY_EXPRESSIONS_USAGE初期化パラメータには、次のオプションがあります。

  • ENABLE

    データベースでは、静的IM式と動的IM式の両方がIM列ストアに移入されます。この値を設定すると、一部の表でインメモリー・フットプリントが増加します。これはデフォルトです。

  • STATIC_ONLY

    静的構成では、IM列ストアでOSON (バイナリJSON)列をキャッシュできます。それらは、IS_JSONチェック制約でマークされます。内部的には、OSON列はSYS_IME_OSONという名前の非表示の仮想列です。

  • DYNAMIC_ONLY

    データベースでは、SYS_IME非表示仮想列として表に追加された、頻繁に使用されているかホットな式のみが移入されます。この値を設定すると、一部の表でインメモリー・フットプリントが増加します。

  • DISABLE

    データベースでは、静的か動的かに関係なく、IM式はIM列ストアに移入されません。

注意:

IM式では、NLS依存のデータ型はサポートされていません。

INMEMORY_EXPRESSIONS_USAGEの値の変更により、現在IM列ストアに移入されているIM式への影響はすぐにはありません。たとえば、INMEMORY_EXPRESSIONS_USAGEDYNAMIC_ONLYからDISABLEに変更した場合は、データベースによって、格納されているIM式はすぐには削除されません。正確に述べると、次の再移入で、無効になっているIM式が除外されます。それにより、効率的にそれらが削除されます。

関連項目:

5.1.3.2 DBMS_INMEMORY_ADMINおよびDBMS_INMEMORY

IM式を管理するには、DBMS_INMEMORY_ADMINおよびDBMS_INMEMORYパッケージを使用します。

IM式を管理するためのPL/SQLプロシージャ

パッケージ プロシージャ 説明

DBMS_INMEMORY_ADMIN

IME_CAPTURE_EXPRESSIONS

このプロシージャは、指定された時間範囲でデータベース内の最も頻繁にアクセスされている(最もホットな)式を20個取得します。

DBMS_INMEMORY_ADMIN

IME_DROP_ALL_EXPRESSIONS

このプロシージャは、データベース内のすべてのSYS_IME仮想列を削除します。

DBMS_INMEMORY_ADMIN

IME_POPULATE_EXPRESSIONS

このプロシージャは、IME_CAPTURE_EXPRESSIONSプロシージャの最後の呼出しで取得されたIM式の移入を強制的に実行します。

DBMS_INMEMORY

IME_DROP_EXPRESSIONS

このプロシージャは、指定された一連のSYS_IME仮想列を表から削除します。

関連項目:

DBMS_INMEMORYおよびDBMS_INMEMORY_ADMINの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照

5.1.4 IM式のための基本作業

INMEMORY_EXPRESSIONS_USAGEのデフォルト設定では、データベースで、動的および静的IM式の両方を使用できます。IM列ストアに式を移入するには、DBMS_INMEMORY_ADMINを使用する必要があります。

通常は、次の順序でIM式の作業を実行します。

  1. 必要な場合は、データベースで使用可能なIM式のタイプを変更します。

    IM式の使用の構成を参照してください。

  2. IM式を取得および移入します。

    IM式の取得および移入を参照してください。

  3. 必要な場合は、IM式の一部またはすべてを削除します。

    IM式の削除を参照してください。

5.2 IM式の使用の構成

必要な場合は、INMEMORY_EXPRESSIONS_USAGEを使用して、移入の対象となるIM式のタイプを選択するか、すべてのIM式の移入を無効にします。

前提条件

データベースでのIM式の使用を可能にするには、次の条件を満たしている必要があります。

  • INMEMORY_SIZE初期化パラメータがゼロ以外の値に設定されている。

  • 初期化パラメータCOMPATIBLEの値が12.2.0以上に設定されている。

注意:

Oracle Real Applications Cluster (RAC)データベースでは、INMEMORY_EXPRESSIONS_USAGE初期化パラメータは、すべてのデータベース・インスタンスで同じ値である必要はありません。各IMCUは、独立して仮想列をリストします。各IMCUで、IMCUが移入または再移入されたときに存在していた初期化パラメータ値および仮想列に基づいて、様々な式をマテリアライズできます。

IM式の使用を構成するには、次の手順を実行します。

  1. 適切な権限があるユーザーとしてデータベースにログインします。

  2. IM式の使用を構成するには、ALTER SYSTEM文を使用して、INMEMORY_EXPRESSIONS_USAGEを次のいずれかの値に設定します。

    • ENABLE (デフォルト): 動的および静的IM式を有効にします

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

    • DYNAMIC_ONLY: 動的IM式のみを有効にします

    • DISABLE: すべてのIM式を無効にします

例5-1 IM式の無効化

次の文は、IM列ストア内のIM式の記憶域を無効にします。

ALTER SYSTEM SET INMEMORY_EXPRESSIONS_USAGE='DISABLE';

関連項目:

INMEMORY_EXPRESSIONS_USAGEの詳細は、『Oracle Databaseリファレンス』を参照してください。

5.3 IM式の取得および移入

IME_CAPTURE_EXPRESSIONSプロシージャは、指定された時間間隔でデータベース内の最も頻繁にアクセスされている(最もホットな)式を20個取得します。IME_POPULATE_EXPRESSIONSプロシージャは、DBMS_INMEMORY_ADMIN.IME_CAPTURE_EXPRESSIONSの最後の呼出しで取得された式の移入を強制的に実行します。

IME_CAPTURE_EXPRESSIONSプロシージャを呼び出したときは必ず、データベースで、式統計ストア(ESS)に問合せが行われ、IM列ストアに少なくとも一部分が移入されているヒープ構成表の式のみが考慮されます。データベースにより、最もホットな20個の式がそれぞれの表に、文字列SYS_IMEという接頭辞が付いた非表示の仮想列として追加され、デフォルトのINMEMORY列圧縮句が適用されます。前の呼出し時に追加されたSYS_IME列が、最新の上位20件のリスト内になくなると、その属性はNO INMEMORYに変わります。

IME_POPULATE_EXPRESSIONSを呼び出さない場合、データベースでは、SYS_IME列は、それらの親IMCUが再移入されるときに段階的に再移入されます。表が再移入されない場合、データベースでは、IME_CAPTURE_EXPRESSIONSプロシージャによって取得された新しいSYS_IME列は再移入されません。IME_POPULATE_EXPRESSIONSは、再移入を強制的に実行することで、この問題を解決します。

IME_POPULATE_EXPRESSIONSプロシージャは、内部的に、INMEMORY属性が指定されているSYS_IME列があるすべての表に対して、DBMS_INMEMORY.REPOPULATEを呼び出します。指定された表サブセット内のSYS_IME列を移入するには、DBMS_INMEMORY_ADMIN.IME_POPULATE_EXPRESSIONSではなくDBMS_INMEMORY.REPOPULATEを使用します。

前提条件

データベースでのIM式の取得を可能にするには、次の条件を満たしている必要があります。

  • INMEMORY_EXPRESSIONS_USAGE初期化パラメータがDISABLE以外の値に設定されている必要があります。

  • INMEMORY_SIZE初期化パラメータがゼロ以外の値に設定されている。

  • 初期化パラメータCOMPATIBLEの値が12.2.0以上に設定されている必要があります。

IM式を取得および移入するには、次の手順を実行します。

  1. 適切な権限があるユーザーとしてデータベースにログインします。

  2. DBMS_INMEMORY_ADMIN.IME_CAPTURE_EXPRESSIONSを次のパラメータのいずれかを指定して実行します。

    • CUMULATIVE: データベースでは、データベース作成以降のすべての式統計が考慮されます。

    • CURRENT: データベースでは、過去24時間の式統計のみが考慮されます。

  3. 必要な場合は、DBMS_INMEMORY_ADMIN.IME_POPULATE_EXPRESSIONSを実行して、最新のIM式をすぐに移入するよう強制します。

例5-2 過去24時間の上位20件のIM式の取得

この例では、最後の日に収集された統計のみを使用してIM式を取得してから、即時移入を強制的に実行します。

EXEC DBMS_INMEMORY_ADMIN.IME_CAPTURE_EXPRESSIONS('CURRENT');
EXEC DBMS_INMEMORY_ADMIN.IME_POPULATE_EXPRESSIONS();

DBA_IM_EXPRESSIONSの次のような問合せでは、2つのIM式が現在移入されていることが示されます(出力例が提供されています)。

COL OWNER FORMAT a6 
COL TABLE_NAME FORMAT a9 
COL COLUMN_NAME FORMAT a25
SET LONG 50
SET LINESIZE 150

SELECT OWNER, TABLE_NAME, COLUMN_NAME, SQL_EXPRESSION 
FROM   DBA_IM_EXPRESSIONS;

OWNER  TABLE_NAM COLUMN_NAME               SQL_EXPRESSION
------ --------- ------------------------- ---------------------------------------------
HR     EMPLOYEES SYS_IME00010000001746FD   12*("SALARY"*NVL("COMMISSION_PCT",0)+"SALARY")
HR     EMPLOYEES SYS_IME00010000001746FE   ROUND("SALARY"*12/52,2)

関連項目:

5.4 IM式の削除

DBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONSプロシージャは、データベース内のすべてのSYS_IME式仮想列を削除します。DBMS_INMEMORY.IME_DROP_EXPRESSIONSプロシージャは、指定された一連のSYS_IME仮想列を表から削除します。

SYS_IME列を削除する一般的な理由は、領域およびパフォーマンスです。属性がINMEMORYNO INMEMORYかに関係なく、表のSYS_IME列の最大数は50個です。1つの表に対して式が上限の50個に達すると、データベースにより、新しいSYS_IME列は追加されなくなります。新しい式のために領域を作り出すには、DBMS_INMEMORY.IME_DROP_EXPRESSIONSまたはDBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONSプロシージャを使用して、SYS_IME列を手動で削除する必要があります。

IME_DROP_ALL_EXPRESSIONSプロシージャは、INMEMORY属性の有無に関係なく、すべての表からすべてのSYS_IME列を削除します。事実上、このプロシージャは、データベース規模のリセット・ボタンの役割を果たします。

IME_DROP_ALL_EXPRESSIONSを使用すると、SYS_IME列があるセグメントのすべてのIMEUおよびIMCUの削除がトリガーされます。たとえば、移入された50個の表にそれぞれ1つのSYS_IME列がある場合は、IME_DROP_ALL_EXPRESSIONSによって、IM列ストアから50個すべての表が削除されます。これらのセグメントを再度移入するには、DBMS_INMEMORY.POPULATEプロシージャを使用するか、表の全体スキャンを実行する必要があります。

前提条件

IM式を削除するには、次の条件を満たしている必要があります。

  • INMEMORY_EXPRESSIONS_USAGE初期化パラメータは、DISABLE以外の値に設定されています。

  • INMEMORY_SIZE初期化パラメータがゼロ以外の値に設定されています。

  • COMPATIBLE初期化パラメータが12.2.0以上に設定されています。

IM式を削除するには、次の手順を実行します。

  1. SQL*PlusまたはSQL Developerで、必要な権限を持つユーザーとしてデータベースにログインします。

  2. DBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONSまたはDBMS_INMEMORY.IME_DROP_EXPRESSIONSのどちらかを実行します。

    IME_DROP_EXPRESSIONSを実行する場合は、次のパラメータを指定します。

    • schema_name : インメモリー表を含むスキーマの名前

    • table_name: インメモリー表の名前

    • column_name: SYS_IME列の名前。デフォルトでこの値はnullで、この表内のすべてのSYS_IME列を指定します。

例5-3 表内のすべてのIM式の削除

この例では、hr.employees表内のすべてのIM式を削除します。

EXEC DBMS_INMEMORY.IME_DROP_EXPRESSIONS('hr', 'employees');

関連項目: