5 インメモリー移入に対するオブジェクトの手動による有効化

INMEMORY_AUTOMATIC_LEVELHIGHに設定されていない場合は、移入のためにオブジェクトを手動で有効または無効にして、圧縮および優先度オプションを設定する必要があります。

ノート:

INMEMORY_AUTOMATIC_LEVELHIGHが設定されていて、INMEMORY_FORCEBASE_LEVELが設定されていない場合は、データベースによって、すべてのオブジェクトでインメモリー移入が自動的に有効になり、必要に応じて移入および削除されます。DDL文に手動でINMEMORY句を指定する必要はありません。

インメモリー移入に対するオブジェクトの手動による有効化について

INMEMORY句のあるオブジェクトのみが、IM列ストアへの移入の対象になります。この句を手動で適用するには、CREATE TABLEALTER TABLEなどのDDL文を使用する必要があります。

インメモリー移入に対するオブジェクトの有効化の目的

オブジェクトにINMEMORY属性がない場合は、そのオブジェクトは移入の対象になりません。

オブジェクトにINMEMORY属性がある場合、そのオブジェクトはIM列ストアに存在している可能性があります。インメモリー移入は個別のステップであり、データベースがディスクから既存の行形式データを読み取って、そのデータを列形式に変換してIM列ストアに格納するときに発生します。

ノート:

移入は、ディスク上の既存のデータを列形式に変換することであり、新しいデータを列形式に変換する再移入とは異なります。IMCUは読取り専用の構造であるため、Oracle Databaseでは、それらは行の変更時に移入されません。正確に述べると、データベースでは、行変更がトランザクション・ジャーナルに記録されてから、再移入の一環として新しいIMCUが作成されます。

INMEMORY_AUTOMATIC_LEVEL初期化パラメータをHIGHに設定すると、すべてのオブジェクトがデフォルトでINMEMORYになり、それによって自動的に移入の対象になります。個別のオブジェクトをINMEMORYとして指定するための手動のDDL文は不要です。INMEMORY_AUTOMATIC_LEVELHIGHでない場合は、手動でINMEMORY句を指定する必要があります。

インメモリー・オブジェクトの制御

インメモリー・アクセスの表領域、表(内部および外部)、パーティションおよびマテリアライズド・ビューを使用可能にできます。圧縮や移入の優先度などのオプションも指定できます。

INMEMORY副句

INMEMORYはセグメントレベルの属性で、列レベルの属性ではありません。ただし、INMEMORY属性を、指定したオブジェクト内の列のサブセットに適用できます。

IM列ストアに対するオブジェクトを有効化または無効化するには、表領域、表およびマテリアライズド・ビューのDDL文にINMEMORY句を指定します。DBA_TABLESビューのINMEMORY列は、どの表にINMEMORY属性が設定されている(ENABLED)か、または設定されていない(DISABLED)かを示します。

次のオブジェクトは、IM列ストアへの移入の対象ではありません。

  • 索引

  • 索引構成表

  • ハッシュ・クラスタ

  • SYSユーザーに所有されているか、SYSTEMまたはSYSAUX表領域内に格納されているオブジェクト

インメモリー表

ヒープ構成表を移入の対象にするには、CREATE TABLE文またはALTER TABLE文でINMEMORY句を指定します。

移入の対象になる列

デフォルトでは、IM列ストアは表内のすべての非仮想列を移入します。内部表のすべての列または一部の列を指定できます。たとえば、oe.product_informationweight_class列およびcatalog_url列を適格性から除外する場合があります。

表をIM列ストアに対して有効化した場合に、その表に次のいずれかのタイプの列が含まれていても、これらはIM列ストアに移入されません。

  • 表外格納列(VARRAY、ネストした表の列、およびアウトラインLOB)

    ノート:

    インラインLOB列の場合、IM列ストアは連続した最大4KBのバッファ記憶域を割り当て、インラインLOBにOSON (バイナリJSON)データが含まれている場合は最大32KBを割り当てます。アウトラインLOBの場合、IM列ストアはロケータに対して最大40バイトを割り当てますが、LOB自体は格納しません。

  • LONGまたはLONG RAWデータ型を使用する列

  • 拡張データ型の列

Oracle Database 21c以降、INMEMORY TEXT句を使用するとインメモリー全文列を指定できます。この列は、CONTAINS()またはJSON_TEXTCONTAINS()演算子を使用した高速インメモリー問合せをサポートするCHARVARCHAR2CLOBBLOBまたはJSONの列です。IM列ストアは、テキスト、JSON、XMLドキュメントなどの列データをドメイン固有のIM形式で格納します。

インメモリー・パーティション表

パーティション表については、INMEMORY句を表レベルで指定できます。パーティション表は、外部パーティションのみ、内部パーティションのみ、または内部パーティションと外部パーティションの両方のハイブリッド混合を保持できます。デフォルトでは、パーティション表内のすべてのパーティションが表レベルのINMEMORY句を継承します。この句は、個別のパーティションに指定することもできます。

Oracle Exadata Storage Serverのフラッシュ・キャッシュの列記憶域

Oracle Exadata Storage Serverでは、CELLMEMORYキーワード(デフォルト)により、フラッシュ・キャッシュはインメモリー形式でデータを格納できます。ALTER TABLEを使用して、FOR QUERYまたはFOR CAPACITY圧縮を選択できます。NO CELLMEMORYを指定すると、フラッシュ・キャッシュ内の列型記憶域が無効になります。

例5-1 表のINMEMORYとしての指定

データベースにユーザーshとして接続していると仮定します。FOR QUERY LOWのデフォルト圧縮レベルを使用して、IM列ストアへの移入のためにcustomers表を有効化します。

SQL> SELECT TABLE_NAME, INMEMORY FROM USER_TABLES WHERE TABLE_NAME = 'CUSTOMERS';

TABLE_NAME INMEMORY
---------- --------
CUSTOMERS  DISABLED

SQL> ALTER TABLE customers INMEMORY;

Table altered.

SQL> SELECT TABLE_NAME, INMEMORY, INMEMORY_COMPRESSION FROM USER_TABLES WHERE TABLE_NAME='CUSTOMERS';

TABLE_NAME INMEMORY INMEMORY_COMPRESS
---------- -------- -----------------
CUSTOMERS  ENABLED  FOR QUERY LOW

関連項目:

インメモリー外部表

外部表を移入の対象にするには、CREATE TABLEまたはALTER TABLEEXTERNAL ... INMEMORY句を指定します。

インメモリー外部表の目的

インメモリー外部表は、次のような場合に役立ちます。

  • 短期間に繰り返しスキャンする必要があり、Oracle Databaseに保存する必要がない短期データ

  • 高速分析処理のためにリレーショナル・データに結合する必要がある外部データ

  • Oracle Databaseと外部ツールの両方で分析問合せによってアクセスされ、データベース記憶域でマテリアライズする必要がないデータ

インメモリー外部表の仕組み

IM列ストアは、ヒープ構成表の場合と同じ方法で外部表のデータを管理します。たとえば、全表スキャンでは、内部表と外部表の両方をIM列ストアに移入します。外部表でサポートされるドライバは、インメモリー外部表でもサポートされます。

インメモリー外部表のユーザー・インタフェース

INMEMORY句は、パーティション化された外部表またはハイブリッド・パーティション表の最上位レベルで指定できます。この句は、どのパーティションにも継承されます。個別のパーティションにINMEMORYを指定することもできます。これにより、外部表内の異なるパーティションに異なるインメモリー指定が可能になります。

ノート:

IM外部表でサポートされていないハイブリッド表にINMEMORY句を指定すると、そのような属性は内部パーティションにのみ継承されます。

インメモリー外部表の制限事項は、次のとおりです。

  • インメモリー外部表では、サブパーティションはサポートされていません。
  • column句、distribute句およびpriority句を含む、外部表の一部のINMEMORY副句は有効ではありません。

  • インメモリー外部表では、結合グループはサポートされていません。

  • インメモリー最適化算術は、外部表をサポートしていません。

  • インメモリー外部表では、IM式はサポートされていません。

  • インメモリー外部表は、Oracle Active Data GuardインスタンスのDISTRIBUTE ... FOR SERVICE句をサポートしていません。

次に示す外部表のディクショナリ・ビューには、INMEMORY列とINMEMORY_COMPRESSION列があります。

  • DBA_XTERNAL_PART_TABLES

  • DBA_XTERNAL_TAB_PARTITIONS

  • DBA_XTERNAL_TAB_SUBPARTITIONS

ノート:

インメモリーの外部表を問い合せるセッションでは、初期化パラメータQUERY_REWRITE_INTEGRITYstale_toleratedに設定する必要があります。

外部表が変更された場合、IM列ストアからの結果は未定義であることに注意してください。パーティションが(値を削除または追加して)変更された場合も、結果は未定義です。これにより、IMベースとIM以外のスキャンの結果に違いが生じる可能性があります。DBMS_INMEMORY.REPOPULATEを実行してIMストアをリフレッシュし、表データと再同期化できます。

関連項目:

インメモリー・マテリアライズド・ビュー

マテリアライズド・ビューを移入の対象にするには、CREATE MATERIALIZED VIEW文またはALTER MATERIALIZED VIEW文でINMEMORYを指定します。

パーティション・マテリアライズド・ビューの場合、IM列ストア内のパーティションのすべて、またはサブセットを移入できます。

関連項目:

ALTER MATERIALIZED VIEWの構文およびセマンティクスについては、Oracle Database SQL言語リファレンスを参照してください

インメモリー表領域

表領域を移入の対象にするには、CREATE TABLESPACE文またはALTER TABLESPACE文で、INMEMORYを指定します。

デフォルトで、表領域内の表およびマテリアライズド・ビューはすべてIM列ストアに対して有効です。表領域内の個々の表およびマテリアライズド・ビューには、異なるINMEMORY属性がある場合があります。個々のデータベース・オブジェクトの属性は、表領域の属性をオーバーライドします。

ノート:

一時表領域はインメモリー移入の対象ではありません。

関連項目:

ALTER TABLESPACEの構文およびセマンティクスについては、『Oracle Database SQL言語リファレンス』を参照してください

インメモリー・オブジェクトの移入の優先順位オプション

IM列ストアに対してオブジェクトを有効にする場合、オブジェクトを移入するタイミングをOracle Databaseで制御することも(デフォルト)、移入キューでのオブジェクトの優先度を決定するレベルを指定することもできます。

Oracle SQLには、移入のためにキューをより細かく制御できるようにするINMEMORY PRIORITY句が組み込まれています。たとえば、あるデータベース・オブジェクトのデータを移入してから他のデータベース・オブジェクトのデータを移入することが、重要になったり重要でなくなったりすることがあります。

ビデオ:

次の表では、サポートされている優先度レベルを説明します。

表5-1 IM列ストアにデータベース・オブジェクトを移入するための優先度レベル

CREATE/ALTERの構文 説明

PRIORITY NONE

データベースでは、要求された場合のみオブジェクトが移入されます。データベース・オブジェクトの全体スキャンによって、IM列ストアへのオブジェクトの移入がトリガーされます。

これは、PRIORITYINMEMORY句に指定されていない場合のデフォルト・レベルです。

PRIORITY LOW

データベースにより、オブジェクトに低い優先順位が割り当てられ、キュー内のその位置に基づいて、起動後にそれが移入されます。移入には、オブジェクトがアクセスされるかどうかは関係ありません。

オブジェクトは、優先度レベルがNONEのデータベース・オブジェクトより前に、IM列ストアに移入されます。データベース・オブジェクトのデータは、優先度レベルがMEDIUMHIGHまたはCRITICALのデータベース・オブジェクトより後に、IM列ストアに移入されます。

PRIORITY MEDIUM

データベースにより、オブジェクトに中間の優先順位が割り当てられ、キュー内のその位置に基づいて、起動後にそれが移入されます。移入には、オブジェクトがアクセスされるかどうかは関係ありません。

データベース・オブジェクトは、優先度レベルがNONEまたはLOWのデータベース・オブジェクトより前に、IM列ストアに移入されます。データベース・オブジェクトのデータは、優先度レベルがHIGHまたはCRITICALのデータベース・オブジェクトより後に、IM列ストアに移入されます。

PRIORITY HIGH

データベースにより、オブジェクトに高い優先順位が割り当てられ、キュー内のその位置に基づいて、起動後にそれが移入されます。移入には、オブジェクトがアクセスされるかどうかは関係ありません。

データベース・オブジェクトのデータは、優先度レベルがNONELOWまたはMEDIUMのデータベース・オブジェクトより前に、IM列ストアに移入されます。データベース・オブジェクトのデータは、優先度レベルがCRITICALのデータベース・オブジェクトより後に、IM列ストアに移入されます。

PRIORITY CRITICAL

データベースにより、オブジェクトに低い優先順位が割り当てられ、キュー内のその位置に基づいて、起動後にそれが移入されます。移入には、オブジェクトがアクセスされるかどうかは関係ありません。

データベース・オブジェクトのデータは、優先度レベルがNONELOWMEDIUMまたはHIGHのデータベース・オブジェクトより前に、IM列ストアに移入されます。

複数のデータベース・オブジェクトの優先度レベルがNONE以外である場合、Oracle Databaseでは、優先度レベルに基づいて移入するオブジェクトのデータをキューに入れます。CRITICAL優先度レベルのデータベース・オブジェクトが最初に移入され、HIGH優先度レベルのデータベース・オブジェクトが次に移入される、といったようになります。IM列ストアに領域が残っていない場合、領域が使用できるようになるまで、他のオブジェクトは移入されません。

ノート:

すべてのオブジェクトをCRITICALとして指定した場合、データベースでは、どのオブジェクトも他より重要とはみなされません。

データベースを再起動すると、優先度レベルがNONE以外のデータベース・オブジェクトのデータはすべて起動時にIM列ストアに移入されます。優先度レベルがNONE以外のデータベース・オブジェクトの場合、そのデータベース・オブジェクトが含指定されているALTER TABLEまたはALTER MATERIALIZED VIEW DDL文は、IM列ストアでDDLの変更が記録されるまで戻りません。

ノート:

  • 優先度レベル設定は、表全体または表パーティションに適用する必要があります。表内の列のサブセットごとに異なるIM列ストア優先度レベルを指定することはできません。

  • ディスク上のセグメントが64KB以下の場合、IM列ストアに移入されません。したがって、IM列ストアに対して有効になっている小規模データベース・オブジェクトは、移入されないことがあります。

関連項目:

インメモリー・オブジェクトの圧縮レベル

要件に応じて、様々なレベルでインメモリー・オブジェクトを圧縮できます。

一般には、圧縮は領域を節約するメカニズムです。ただし、IM列ストアでは、問合せパフォーマンスも向上させるアルゴリズムを使用して、データを圧縮できます。列データにMEMCOMPRESS FOR DMLまたはMEMCOMPRESS FOR QUERYオプションを使用すると、圧縮されたデータに対してSQL問合せが直接実行されます。そのため、スキャンおよびフィルタ操作は、少量のデータに対して行います。データベースでは、結果セットに必要な場合のみ、データが解凍されます。

ビデオ:

V$IM_SEGMENTSおよびV$IM_COLUMN_LEVELビューでは、現在の圧縮レベルが示されます。適切なALTERコマンドを使用することで、圧縮レベルを変更できます。表が現在IM列ストアに移入されており、PRIORITY以外の表のINMEMORY属性を変更した場合は、データベースでその表がIM列ストアから除去されます。再移入の動作は、PRIORITY設定によって異なります。

INMEMORY_FORCE初期化パラメータにBASE_LEVELが設定されている場合は、INMEMORYオブジェクトおよび列でQUERY LOW圧縮が自動的に使用されます。データ・ディクショナリ・ビューには既存の圧縮設定が引き続き表示される場合がありますが、ベース・レベルでは常にオブジェクトおよび列がQUERY LOWレベルで透過的に圧縮されます。

次の表は、有効なINMEMORY MEMCOMPRESS句のまとめを示しています。

表5-2 IM列ストアの圧縮レベル

CREATE/ALTER … INMEMORY構文 説明

NO MEMCOMPRESS

データは圧縮されません。

MEMCOMPRESS FOR DML

このレベルでは、DMLのパフォーマンスが最適になります。

このレベルでは、NO MEMCOMPRESSを例外として、IM列ストアのデータが最も小さく圧縮されます。

ノート: この圧縮レベルは、Exadataフラッシュ・キャッシュのCELLMEMORY記憶域ではサポートされません。

MEMCOMPRESS FOR QUERY LOW

このレベルは、問合せパフォーマンスが最適になります。

IM列ストア・データの圧縮は、MEMCOMPRESS FOR DMLを上回りますが、MEMCOMPRESS FOR QUERY HIGHを下回ります。

このレベルは次のシナリオではデフォルトです。

  • CREATEまたはALTER SQL文で、INMEMORY句が圧縮レベルなしで指定されている。

  • MEMCOMPRESS FOR QUERYLOWまたはHIGHを含めずに指定されている。

  • INMEMORY_FORCE初期化パラメータにBASE_LEVELが設定されている。この場合、手動の圧縮設定に関係なく、IM列ストアはQUERY LOWレベルを透過的に適用します。

MEMCOMPRESS FOR QUERY HIGH

このレベルでは、問合せパフォーマンスが向上し、領域が節約されます。

IM列ストアデータの圧縮は、MEMCOMPRESS FOR QUERY LOWを上回りますが、MEMCOMPRESS FOR CAPACITY LOWを下回ります。

MEMCOMPRESS FOR CAPACITY LOW

このレベルでは、領域節約になるような方向で、領域節約と問合せパフォーマンスのバランスがとられます。

IM列ストア・データの圧縮は、MEMCOMPRESS FOR QUERY HIGHを上回りますが、MEMCOMPRESS FOR CAPACITY HIGHを下回ります。このレベルでは、Oracle Zip (OZIP)という独自の圧縮技術が適用されます。これにより、Oracle Database専用に調整されている、非常に高速な解凍が提供されます。そのデータは、スキャンするより前に解凍する必要があります。

このレベルは、LOWまたはHIGHのいずれかを指定せずにMEMCOMPRESS FOR CAPACITYが指定されている場合のデフォルトです。

MEMCOMPRESS FOR CAPACITY HIGH

このレベルでは、最も優れた領域節約がもたらされます。

IM列ストア・データを最も大きく圧縮します。

MEMCOMPRESS AUTO

このレベルは、INMEMORY_AUTOMATIC_LEVELHIGHに設定している場合にのみ該当します。この場合、データベースはMEMCOMPRESS AUTOによって自動的にすべてのセグメントを有効化します。ただし、手動で特定のセグメントをNO INMEMORYに設定することもできます。そのようなNO INMEMORYセグメントに後からINMEMORY属性を再適用する場合は、INMEMORY MEMCOMPRESS AUTO句を指定します。

関連項目:

Oracle Compression Advisor

Oracle Compression AdvisorではMEMCOMPRESS句を使用してユーザーが実感できる圧縮率を推定します。アドバイザはDBMS_COMPRESSIONインタフェースを使用します。

表に対してDBMS_COMPRESSION.GET_COMPRESSION_RATIOを実行すると、Oracle Databaseにより、行のサンプルが分析されます。このため、Oracle Compression Advisorでは、IM列ストアに移入された後に表が得られる圧縮結果について、適切な見積りが提供されます。

関連項目:

DBMS_COMPRESSION.GET_COMPRESSION_RATIOについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

IM列ストアに対する表の有効化および無効化

IM列ストアに対して表を有効にするには、CREATE TABLEまたはALTER TABLE文でINMEMORY句を指定します。IM列ストアに対して表を無効にするには、CREATE TABLEまたはALTER TABLE文でNO INMEMORY句を指定します。

インメモリー列ストアに対する新しい表の有効化

新しい表をIM列ストアに対して有効にするには、CREATE TABLE文でINMEMORY句を指定します。

IM列ストアに対して内部表または外部表のいずれかを有効にできます。列および優先度の副句を含む、一部のINMEMORY副句は、外部表に対して有効ではありません。

前提条件

IM列ストアがデータベースに対して有効になっていることを確認します。CDBまたはPDBに対するIM列ストアの有効化を参照してください。

新しい表をIM列ストアに対して有効にするには:

  1. 表の作成に必要な権限があるユーザーとして、データベースにログインします。

  2. INMEMORY句を指定してCREATE TABLE文を実行します。

IM列ストアに対する既存の表の有効化および無効化

既存の表をIM列ストアに対して有効または無効にするには、ALTER TABLE文でINMEMORY句またはNO INMEMORY句を指定します。

前提条件

IM列ストアがデータベースに対して有効になっていることを確認します。CDBまたはPDBに対するIM列ストアの有効化を参照してください。

IM列ストアに対して既存の表を有効または無効にするには:

  1. ALTER TABLE権限のあるユーザーとしてデータベースにログインします。

  2. INMEMORY句またはNO INMEMORY句を指定してALTER TABLE文を実行します。

  3. 必要な場合は、インメモリー・セグメントに関するメタデータ(サイズ、優先順位、圧縮レベル)を表示するために、V$IM_SEGMENTSを問い合せます。

IM列ストアに対する表の有効化および無効化

次の例では、IM列ストアに対して表を有効化または無効化する方法を示します。

インメモリー表の作成: 例

この例では、test_inmem表を作成し、IM列ストアに対して有効にします。

この例では、test_inmem表を作成し、IM列ストアに対して有効にします。SQL*Plusで、表を所有するユーザーとしてデータベースにログインし、次のSQL文を実行します。

CREATE TABLE test_inmem ( id NUMBER(5) PRIMARY KEY, test_col VARCHAR2(15)) INMEMORY;

上の文では、INMEMORY句のデフォルトであるMEMCOMPRESS FOR QUERYおよびPRIORITY NONEが使用されます。PRIORITYNONEになっているため、データベースは自動的に表を移入しません。

新しい表を事前移入するには、CTAS (CREATE TABLE AS SELECT)文を使用して作成し、同時に、Oracleが提供するshサンプル・スキーマからデータをプルする次の文を使用して、新しい表でインメモリーを有効にします。
CREATE TABLE test_inmem INMEMORY AS SELECT * FROM sh.sales; 
INMEMORY 副句を含めることもできます:
CREATE TABLE test_inmem INMEMORY MEMCOMPRESS for capacity high AS SELECT * FROM sh.sales;
次の文の形式は正しくないことに注意してください。INMEMORY 句および関連する副句は、SELECTの前に置く必要があります。ここでは、SELECTの後に追加されています:
CREATE TABLE test_inmem AS SELECT * from sh.sales INMEMORY MEMCOMPRESS for capacity high;
この誤った使用方法では、INMEMORYは予約語ではなくキーワードとして解釈されます。暗黙的に無視され、INMEMORYは無効のままです。MEMCOMPRESSはキーワードとしても解釈されますが、エラーが発生します。
インメモリー・パーティションを使用した表の作成: 例

この例では、パーティションのサブセットをINMEMORYとして指定して、range_salesという名前のパーティション表を作成します。

新しい表を所有するユーザーとしてSQL*Plusにログインし、次のDDL文を実行します。

CREATE TABLE range_sales
    ( prod_id        NUMBER(6)
    , cust_id        NUMBER
    , time_id        DATE
    , channel_id     CHAR(1)
    , promo_id       NUMBER(6)
    , quantity_sold  NUMBER(3)
    , amount_sold    NUMBER(10,2)
    ) 
PARTITION BY RANGE (time_id)
  (PARTITION SALES_Q4_1999 
      VALUES LESS THAN (TO_DATE('01-JAN-2015','DD-MON-YYYY'))
      INMEMORY MEMCOMPRESS FOR DML,
   PARTITION SALES_Q1_2000 
      VALUES LESS THAN (TO_DATE('01-APR-2015','DD-MON-YYYY'))
      INMEMORY MEMCOMPRESS FOR QUERY,
   PARTITION SALES_Q2_2000 
      VALUES LESS THAN (TO_DATE('01-JUL-2015','DD-MON-YYYY'))
      INMEMORY MEMCOMPRESS FOR CAPACITY,
   PARTITION SALES_Q3_2000 
      VALUES LESS THAN (TO_DATE('01-OCT-2015','DD-MON-YYYY'))
      NO INMEMORY,
   PARTITION SALES_Q4_2000 
      VALUES LESS THAN (MAXVALUE));

前述のSQLでは、IM列ストア内の最初の3つのパーティションに対して、異なる圧縮レベルを指定しています。最後の2つのパーティションは、IM列ストアへの移入の対象ではありません。

インメモリー外部表の作成: 例

この例では、INMEMORYオプションを使用して外部表を作成します。

この例では、ホストにディレクトリ/tmp/data//tmp/log/および/tmp/bad/があることを前提としています。

次のSQLスクリプトは、sh.sales表からカンマ区切りのフラット・ファイル/tmp/data/sh_sales.csvを作成します。ユーザーshとしてスクリプトを実行します。

SET HEAD OFF
SET TRIMSPOOL ON
SET PAGES 0
SET FEEDBACK OFF
SET TERMOUT OFF
SPOOL /tmp/data/sh_sales.csv
SELECT prod_id       || ',' || cust_id  || ',' || time_id || ',' || 
       channel_id    || ',' || promo_id || ',' || 
       quantity_sold || ',' || amount_sold 
FROM   sales;
SPOOL OFF

sh_sales.csvファイルを使用して、次のSQLスクリプトはINMEMORYオプションで外部表sh.admin_ext_salesを作成します。

CONNECT  /  AS SYSDBA;
-- Set up directories and grant access to sh 
CREATE OR REPLACE DIRECTORY admin_dat_dir
    AS '/tmp/data'; 
CREATE OR REPLACE DIRECTORY admin_log_dir 
    AS '/tmp/log'; 
CREATE OR REPLACE DIRECTORY admin_bad_dir 
    AS '/tmp/bad'; 
GRANT READ ON DIRECTORY admin_dat_dir TO sh; 
GRANT WRITE ON DIRECTORY admin_log_dir TO sh; 
GRANT WRITE ON DIRECTORY admin_bad_dir TO sh;
-- sh connects. Provide the user password (sh) when prompted.
CONNECT sh
-- create the external table
DROP TABLE admin_ext_sales;
CREATE TABLE admin_ext_sales
     (  prod_id           NUMBER, 
        cust_id           NUMBER,
        time_id           DATE, 
        channel_id        NUMBER,
        promo_id          NUMBER,
        quantity_sold     NUMBER(10,2),
        amount_sold       NUMBER(10,2)
     ) 
     ORGANIZATION EXTERNAL 
     ( TYPE ORACLE_LOADER 
       DEFAULT DIRECTORY admin_dat_dir 
       ACCESS PARAMETERS 
       ( records delimited by newline 
         badfile admin_bad_dir:'empxt%a_%p.bad' 
         logfile admin_log_dir:'empxt%a_%p.log' 
         fields terminated by ',' 
         missing field values are null 
         ( prod_id, cust_id,
           time_id char date_format date mask "dd-mon-yy", 
           channel_id, promo_id, quantity_sold, amount_sold 
         ) 
       ) 
       LOCATION ('sh_sales.csv') 
     ) 
     REJECT LIMIT UNLIMITED
     INMEMORY; 

ALL_EXTERNAL_TABLESの次の問合せでは、admin_ext_salesINMEMORYに対して有効になっていることを示しています。

COL OWNER FORMAT A10
COL TABLE_NAME FORMAT A15

SELECT OWNER, TABLE_NAME, 
       INMEMORY, INMEMORY_COMPRESSION 
FROM   ALL_EXTERNAL_TABLES 
WHERE  TABLE_NAME = 'ADMIN_EXT_SALES';

OWNER      TABLE_NAME      INMEMORY INMEMORY_COMPRESS
---------- --------------- -------- -----------------
SH         ADMIN_EXT_SALES ENABLED  FOR QUERY LOW

関連するビューには、ALL_XTERNAL_PART_TABLESALL_XTERNAL_TAB_PARTITIONSおよびALL_XTERNAL_TAB_SUBPARTITIONSが含まれます。

関連項目:

パーティション化されたインメモリー外部表の作成: 例

この例では、INMEMORYオプションを使用してパーティション化された外部表を作成します。

この例では、ホストにディレクトリ/tmp/data//tmp/log/および/tmp/bad/があることを前提としています。

  1. shユーザーとしてデータベースにログインします。

  2. 次のSQLスクリプトを実行すると、カンマ区切りのフラット・ファイル/tmp/data/sh_sales_98.csv/tmp/data/sh_sales_99.csvsh.sales表から作成されます。

    SET ECHO OFF
    SET HEAD OFF
    SET TAB OFF
    SET PAGES 0
    SET TRIMSPOOL ON
    SET FEEDBACK OFF
    SET TERMOUT OFF
    SPOOL /tmp/data/sh_sales_98.csv
    SELECT prod_id       || ',' || cust_id  || ',' || time_id || ',' || 
           channel_id    || ',' || promo_id || ',' || 
           quantity_sold || ',' || amount_sold 
    FROM   sales
    WHERE  time_id < TO_DATE('1999-01-01','SYYYY-MM-DD','NLS_CALENDAR=GREGORIAN');
    SPOOL OFF
    SPOOL /tmp/data/sh_sales_99.csv
    SELECT prod_id       || ',' || cust_id  || ',' || time_id || ',' || 
           channel_id    || ',' || promo_id || ',' || 
           quantity_sold || ',' || amount_sold 
    FROM   sales
    WHERE  time_id > TO_DATE('1998-12-31','SYYYY-MM-DD','NLS_CALENDAR=GREGORIAN')
    AND    time_id < TO_DATE('2000-01-01','SYYYY-MM-DD','NLS_CALENDAR=GREGORIAN');
    SPOOL OFF
  3. 次のSQLスクリプトを実行して、INMEMORYオプションを指定した外部表sh.admin_ext_pt_salesを作成します。

    CONNECT  /  AS SYSDBA;
    -- Set up directories and grant access to sh 
    CREATE OR REPLACE DIRECTORY admin_dat_dir
        AS '/tmp/data'; 
    CREATE OR REPLACE DIRECTORY admin_log_dir 
        AS '/tmp/log'; 
    CREATE OR REPLACE DIRECTORY admin_bad_dir 
        AS '/tmp/bad'; 
    GRANT READ ON DIRECTORY admin_dat_dir TO sh; 
    GRANT WRITE ON DIRECTORY admin_log_dir TO sh; 
    GRANT WRITE ON DIRECTORY admin_bad_dir TO sh;
    -- sh connects. Provide the user password (sh) when prompted.
    CONNECT sh
    -- create the external partitioned table
    DROP TABLE admin_ext_pt sales;
    CREATE TABLE admin_ext_pt_sales
         (  prod_id           NUMBER, 
            cust_id           NUMBER,
            time_id           DATE, 
            channel_id        NUMBER,
            promo_id          NUMBER,
            quantity_sold     NUMBER(10,2),
            amount_sold       NUMBER(10,2)
         ) 
         ORGANIZATION EXTERNAL 
         ( TYPE ORACLE_LOADER 
           DEFAULT DIRECTORY admin_dat_dir 
           ACCESS PARAMETERS 
           ( records delimited by newline 
             badfile admin_bad_dir:'empxt%a_%p.bad' 
             logfile admin_log_dir:'empxt%a_%p.log' 
             fields terminated by ',' 
             missing field values are null 
             ( prod_id, cust_id,
               time_id char date_format date mask "dd-mon-yy", 
               channel_id, promo_id, quantity_sold, amount_sold 
             ) 
           )  
         )
         REJECT LIMIT UNLIMITED INMEMORY
         PARTITION BY RANGE (time_id)
         ( PARTITION sales_1998 VALUES LESS THAN
            (TO_DATE('1996-01-01 00:00:00','SYYYY-MM-DD HH24:MI:SS','NLS_CALENDAR=GREGORIAN'))
               LOCATION('sh_sales_98.csv'),
           PARTITION sales_1999 VALUES LESS THAN
            (TO_DATE('1997-01-01 00:00:00','SYYYY-MM-DD HH24:MI:SS','NLS_CALENDAR=GREGORIAN'))
               LOCATION('sh_sales_99.csv')
         );

    ノート:

    表レベルではなく個別のパーティションにINMEMORY属性を適用するには、その属性をPARTITION ... LOCATION('part_name')句の直後に指定します。

  4. ALL_EXTERNAL_TABLESを問い合せることで、INMEMORYについてadmin_ext_pt_sales表が使用可能であることを確認します。

    COL OWNER FORMAT A10
    COL TABLE_NAME FORMAT A18
    
    SELECT OWNER, TABLE_NAME, 
           INMEMORY, INMEMORY_COMPRESSION 
    FROM   ALL_EXTERNAL_TABLES 
    WHERE  TABLE_NAME = 'ADMIN_EXT_PT_SALES';
    
    OWNER      TABLE_NAME         INMEMORY INMEMORY_COMPRESS
    ---------- ------------------ -------- -----------------
    SH         ADMIN_EXT_PT_SALES ENABLED  FOR QUERY LOW
    

    関連するビューには、ALL_XTERNAL_PART_TABLESALL_XTERNAL_TAB_PARTITIONSおよびALL_XTERNAL_TAB_SUBPARTITIONSが含まれます。

  5. IM列ストアにadmin_ext_pt_salesを移入します。

    EXEC DBMS_INMEMORY.POPULATE('SH', 'ADMIN_EXT_PT_SALES');
  6. admin_ext_pt_salesパーティションの移入ステータスを問い合せます。

    COL OWNER FORMAT a3
    COL NAME FORMAT a18
    COL PARTITION FORMAT a13
    COL STATUS FORMAT a9
    COL BNP FORMAT 99999
    
    SELECT OWNER, SEGMENT_NAME NAME, PARTITION_NAME PARTITION,
           POPULATE_STATUS STATUS, BYTES_NOT_POPULATED AS "BNP"
    FROM   V$IM_SEGMENTS;
    
    OWN NAME               PARTITION     STATUS       BNP
    --- ------------------ ------------- --------- ------
    SH  ADMIN_EXT_PT_SALES SALES_1998    COMPLETED      0
    SH  ADMIN_EXT_PT_SALES SALES_1999    COMPLETED      0

    この問合せは、2つの内部パーティションのみが移入されたことを示しています。

関連項目:

ハイブリッド外部表の作成および移入: 例

この例では、INMEMORYオプションを使用してハイブリッド外部表を作成し、内部と外部の両方のパーティションに移入します。

この例では、sh.sales表が存在することを前提としています。目標は、2つの内部パーティションのあるハイブリッド・パーティション表sales_hptを作成することです。そのうちの1つはsh.salesのデータを使用し、次に外部パーティションを1つ追加します。INMEMORY属性をsales_hptに適用すると、この属性がすべてのパーティションに適用されます。

  1. Linuxで一時ディレクトリを作成し、1行の売上データを含むテキスト・ファイルを作成します。

    rm -rf /tmp/sales_data
    mkdir /tmp/sales_data
    echo "1002,110,19-MAR-2016,12,18,150,4800" > /tmp/sales_data/sales2016_data.txt
  2. SQL*Plusで、管理者権限でログインして売上データ用のディレクトリ・オブジェクトを作成します。

    CONNECT / AS SYSDBA
    CREATE DIRECTORY sales_data AS '/tmp/sales_data';
    GRANT READ,WRITE ON DIRECTORY sales_data TO sh;
    
  3. ユーザーshとしてログインし、sales_hpt表を作成します。

    CONNECT sh
    
    DROP TABLE sales_hpt;
    CREATE TABLE sales_hpt
      ( prod_id       NUMBER        NOT NULL,
        cust_id       NUMBER        NOT NULL,
        time_id       DATE          NOT NULL,
        channel_id    NUMBER        NOT NULL,
        promo_id      NUMBER        NOT NULL,
        quantity_sold NUMBER(10,2)  NOT NULL,
        amount_sold   NUMBER(10,2)  NOT NULL
      )
        EXTERNAL PARTITION ATTRIBUTES (
          TYPE ORACLE_LOADER 
          DEFAULT DIRECTORY sales_data
           ACCESS PARAMETERS(
             FIELDS TERMINATED BY ','
             (prod_id,cust_id,time_id DATE 'dd-mm-yyyy',channel_id,promo_id,quantity_sold,amount_sold)
           ) 
          REJECT LIMIT UNLIMITED
         ) 
        PARTITION BY RANGE (time_id)
        (
         PARTITION sales_2014 VALUES LESS THAN (TO_DATE('01-01-2015','dd-mm-yyyy')),
         PARTITION sales_2015 VALUES LESS THAN (TO_DATE('01-01-2016','dd-mm-yyyy')),
         PARTITION sales_2016 VALUES LESS THAN (TO_DATE('01-01-2017','dd-mm-yyyy')) 
           EXTERNAL LOCATION ('sales2016_data.txt')
    );

    前述の文では、表にsales_2014sales_2015およびsales_2016の3つのパーティションがあります。sales_2016のみが外部として指定されています。

  4. データ・ディクショナリを問い合せて、表がハイブリッドになっていることを確認します(出力例も示します)。

    COL TABLE_NAME FORMAT a25
    SELECT TABLE_NAME, HYBRID FROM USER_TABLES WHERE HYBRID = 'YES';
    
    TABLE_NAME                HYB
    ------------------------- ---
    SALES_HPT                 YES
  5. 内部パーティションのsales_2014sales_2015に行を挿入します。

    INSERT INTO sh.sales_hpt (SELECT * FROM sales);
    INSERT INTO sh.sales_hpt 
      VALUES (30, 21086, TO_DATE('2015-12-30','SYYYY-MM-DD'), 2, 999, 1, 10.19);
    COMMIT;

    前述の文の最初の部分で、すべての行がsales表から挿入されます。salesのすべての日付は2002より前です。そのため、salesのすべての行がsales_2014パーティションに挿入されます。2番目の文は、sales_2015パーティションに1行を挿入します。

  6. パーティションを問い合せて、正しいデータが存在することを確認します。

    SQL> SELECT COUNT(*) FROM sales_hpt PARTITION(sales_2014);
    
      COUNT(*)
    ----------
        918843
    
    SQL> SELECT COUNT(*) FROM sales_hpt PARTITION(sales_2015);
    
      COUNT(*)
    ----------
             1
    
    SQL> SELECT COUNT(*) FROM sales_hpt PARTITION(sales_2016);
    
      COUNT(*)
    ----------
             1
  7. INMEMORY属性を表レベルで適用し、データベースに対して強制的に表をIM列ストアに移入させます。

    ALTER TABLE sales_hpt INMEMORY;
    EXEC DBMS_INMEMORY.POPULATE('SH', 'SALES_HPT');
  8. sales_hptパーティションの移入ステータスを問い合せます。

    COL OWNER FORMAT a3
    COL SEGMENT FORMAT a18
    COL PARTITION FORMAT a13
    COL STATUS FORMAT a9
    COL BNP FORMAT 99999
    
    SELECT OWNER, SEGMENT_NAME SEGMENT, PARTITION_NAME PARTITION,
           IS_EXTERNAL AS EXT, POPULATE_STATUS STATUS, 
           BYTES_NOT_POPULATED AS "BNP"
    FROM   V$IM_SEGMENTS
    WHERE  SEGMENT_NAME = 'SALES_HPT'
    ORDER BY PARTITION;
    
    OWN SEGMENT            PARTITION     EXT   STATUS       BNP
    --- ------------------ ------------- ----- --------- ------
    SH  SALES_HPT          SALES_2014    FALSE COMPLETED      0
    SH  SALES_HPT          SALES_2015    FALSE COMPLETED      0
    SH  SALES_HPT          SALES_2016    TRUE  COMPLETED      0

    問合せによって、すべてのパーティション(内部と外部の両方)が移入されていることが示されます。

IM列ストアに対する既存の表の有効化: 例

この例では、IM列ストアに対して既存のsh.sales表を有効にします。

SQL*Plusで、shユーザーとしてデータベースにログインし、次のDDL文を実行します。

ALTER TABLE sales INMEMORY;

上の文では、INMEMORY句のデフォルトであるMEMCOMPRESS FOR QUERYおよびPRIORITY NONEが使用されます。

インメモリー圧縮をFOR CAPACITY LOWに設定する方法: 例

この例では、IM列ストアに対して既存のoe.product_information表を有効にし、圧縮方法FOR CAPACITY LOWを指定します。

SQL*Plusで、oeユーザーとしてデータベースにログインし、次のDDL文を実行します。

ALTER TABLE product_information 
  INMEMORY 
  MEMCOMPRESS FOR CAPACITY LOW;

上の文では、NONEPRIORITY句にデフォルトを使用しています。次のように全表スキャンを強制的に実行して表に移入します(出力例も示します)。

SELECT /*+ FULL(p) NO_PARALLEL(p) */ COUNT(*) 
FROM   product_information p;

  COUNT(*)
----------
       288

別のセッションで、管理権限を持つユーザーとしてログインし、次の問合せを実行して圧縮率を計算します(出力例も示します)。

COL OWNER FORMAT a5
COL SEGMENT_NAME FORMAT a19
SET PAGESIZE 50000

SELECT OWNER, SEGMENT_NAME, BYTES ORIG_SIZE,
       INMEMORY_SIZE IN_MEM_SIZE,
       ROUND (BYTES / INMEMORY_SIZE, 2) COMP_RATIO
FROM   V$IM_SEGMENTS
WHERE  SEGMENT_NAME LIKE 'P%'
ORDER BY 4;

OWNER SEGMENT_NAME         ORIG_SIZE IN_MEM_SIZE COMP_RATIO
----- ------------------- ---------- ----------- ----------
OE    PRODUCT_INFORMATION      98304     1310720        .08
インメモリー優先度をHIGHに設定する方法:例

この例では、IM列ストアに対してoe.product_information表を有効にし、表データをIM列ストアに移入するためにPRIORITY HIGHを指定します。

SQL*Plusで、oeユーザーとしてデータベースにログインし、次のDDL文を実行します。

ALTER TABLE 
  product_information 
  INMEMORY 
  PRIORITY HIGH;
インメモリー表の圧縮および優先順位の設定の変更: 例

この例では、FOR CAPACITY HIGH表圧縮とLOW優先順位設定を使用するように、oe.product_information表を変更します。

SQL*Plusで、管理ユーザーとしてデータベースにログインし、次の問合せを実行して、oe.product_information表の現在の優先度と圧縮設定を表示します。

COL OWNER FORMAT a5
COL SEGMENT_NAME FORMAT a19
SET PAGESIZE 50000

SELECT v.OWNER, v.SEGMENT_NAME, v.INMEMORY_PRIORITY,
       v.INMEMORY_COMPRESSION
FROM   V$IM_SEGMENTS v
WHERE  SEGMENT_NAME LIKE 'P%';

OWNER SEGMENT_NAME        INMEMORY INMEMORY_COMPRESS
----- ------------------- -------- -----------------
OE    PRODUCT_INFORMATION HIGH     FOR CAPACITY LOW

次のDDL文では、oe.product_informationが、FOR CAPACITY HIGH表圧縮およびPRIORITY LOWを使用するよう変更されます。

ALTER TABLE oe.product_information 
  INMEMORY 
  MEMCOMPRESS FOR CAPACITY HIGH 
  PRIORITY LOW;
IM列ストアに対する表の無効化: 例

IM列ストアに対して表を無効にするには、NO INMEMORY句を指定します。

ユーザーoeとしてデータベースにログインし、次の文を実行して、IM列ストアのproduct_information表を無効にします。

ALTER TABLE oe.product_information NO INMEMORY;

V$IM_SEGMENTSビューは、IM列ストアに移入されているデータベース・オブジェクトをリストします。

Exadataスマート・フラッシュ・キャッシュでの列形式の無効化: 例

この例では、Exadataスマート・フラッシュ・キャッシュ記憶域のoe.product_informationの列形式を無効にします。

デフォルトでは、Exadataスマート・フラッシュ・キャッシュは、レベルMEMCOMPRESS FOR CAPACITY LOWを使用してデータを圧縮します。圧縮レベルを変更するか、列形式を完全に無効にするには、ALTER TABLE ... NO CELLMEMORY文を使用します。

ユーザーoeとしてデータベースにログインし、次のDDL文を実行します。

ALTER TABLE product_information NO CELLMEMORY;

インメモリー表に対する列の有効化および無効化

内部表内の個々の列にINMEMORY句を指定できます。外部表は、列レベルでのINMEMORYの指定をサポートしません。

インメモリー列について

内部表の場合、インメモリー仮想列(IM仮想列)および非仮想列の両方がIM移入の対象です。外部表の場合、適格なのは非仮想列のみです。

選択列

デフォルトでは、INMEMORY表のすべての列はIM列ストアに対して有効になっているために移入の対象になります。メモリーを節約するために、IM列ストアの対象にならない列のサブセットを作成できます。

ノート:

INMEMORY_FORCE初期化パラメータにBASE_LEVELが設定されている場合は、INMEMORYオブジェクトおよび列でQUERY LOW圧縮が自動的に使用されます。データ・ディクショナリ・ビューには既存の圧縮設定が引き続き表示される場合がありますが、ベース・レベルでは常にオブジェクトおよび列がQUERY LOWレベルで透過的に圧縮されます。

NO INMEMORY属性

INMEMORY表の一部の列にNO INMEMORYが指定されているときには、INMEMORY列のみが移入の対象になります。

ノート:

除外する列は、表レベルでのみ指定できます。パーティションまたはサブパーティションには指定できません

列のサブセットにNO INMEMORY属性を適用するには、ALTER TABLE table_name INMEMORY ... NO INMEMORY excluded_columnsを指定します。このexcluded_columnsNO INMEMORY列のリストです。NO INMEMORY属性のない列(除外される列のリストに存在しない列)のみが、セグメント・レベルのINMEMORY属性を継承します。

次のDDL文は、employees内のすべての列をインメモリーに対して有効にしますが、salary列は除外します。

ALTER TABLE hr.employees INMEMORY NO INMEMORY (salary);

次の問合せV$IM_COLUMN_LEVELは、給与がNO INMEMORYになっていることを示しています。

COL TABLE_NAME FORMAT a20
COL COLUMN_NAME FORMAT a20
SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION 
FROM   V$IM_COLUMN_LEVEL
WHERE  TABLE_NAME = 'EMPLOYEES'
ORDER BY COLUMN_NAME;

TABLE_NAME           COLUMN_NAME          INMEMORY_COMPRESSION
-------------------- -------------------- --------------------------
EMPLOYEES            COMMISSION_PCT       DEFAULT
EMPLOYEES            DEPARTMENT_ID        DEFAULT
EMPLOYEES            EMAIL                DEFAULT
EMPLOYEES            EMPLOYEE_ID          DEFAULT
EMPLOYEES            FIRST_NAME           DEFAULT
EMPLOYEES            HIRE_DATE            DEFAULT
EMPLOYEES            JOB_ID               DEFAULT
EMPLOYEES            LAST_NAME            DEFAULT
EMPLOYEES            MANAGER_ID           DEFAULT
EMPLOYEES            PHONE_NUMBER         DEFAULT
EMPLOYEES            SALARY               NO INMEMORY

関連項目:

インメモリー・ハイブリッド・スキャン

インメモリー・ハイブリッド・スキャンでは、移入されていない列がある場合に、IM列ストアの表にアクセスします。

Oracle Database 21cより前は、問合せがNO INMEMORY設定の列を参照していた場合、その問合せは行ストアからすべてのデータにアクセスしました。そのため、表スキャンでは列形式や述語プッシュダウンダウンなどのインメモリー機能を利用できませんでした。Oracle Database 21c以降では、INMEMORY列とNO INMEMORY列の両方を参照する問合せが列データにアクセスできます。

場合によっては、インメモリー・ハイブリッド・スキャンによってパフォーマンスを桁違いに向上させることができます。問合せに選択フィルタがある場合は、パフォーマンスが最大に向上します。この場合、IM列ストアは、行ストアで少数の行のみが投影されるように、ほとんどの行をフィルタですばやく除外できます。

最適なパフォーマンスを実現するために、オプティマイザは各種のアクセス方法を比較します。オプティマイザが表スキャンを選択した場合、記憶域エンジンは、通常の行ストア・スキャンよりもインメモリー・ハイブリッド・スキャンのほうがパフォーマンスが優れているかどうかを自動的に判断します。次の条件が満たされるときに、オプティマイザはハイブリッド・スキャンを考慮に入れます。

  • 述語にはINMEMORY列のみが含まれていること。

  • SELECTリストには、INMEMORY列とNO INMEMORY列の任意の組合せが含まれていること。

たとえば、employees表のsalary列とcommission_pct列がINMEMORYと指定されているとします。first_name列は、ほとんど参照されないため、NO INMEMORYになっています。次の問合せはNO INMEMORY列とINMEMORY列の両方を参照するため、ハイブリッドIMスキャンの対象になります。

SELECT first_name FROM employees WHERE salary=6000 ORDER BY first_name;

SELECT first_name, salary AS base_sal, ((salary*commission_pct)+salary) AS total_sal 
FROM   employees 
WHERE  commission_pct=.1
ORDER BY total_sal DESC;

インメモリー・ハイブリッド・スキャンでは、論理的に作業を2つに分割します。その1つはIM列ストアに対する問合せを処理する部分で、もう1つは行ストアに対する問合せを処理する部分です。実行計画では、TABLE ACCESS INMEMORY FULL (HYBRID)という操作はハイブリッド・スキャンを示します。実行時統計が、行ストアにのみアクセスすることでパフォーマンスが高くなることを示している場合、データベースは実行時にインメモリー・ハイブリッド・スキャンを無効にすることがあります。

例5-2 インメモリー・ハイブリッド・スキャン

この例では、amount_soldを除くすべてのsales列に対してインメモリー・アクセスを有効にします。

SH@21c:21c> ALTER TABLE sales INMEMORY NO INMEMORY (amount_sold);

Table altered.

IM列ストアに表を移入します。

SH@21c:21c> SELECT /*+ FULL(sales) NO_PARALLEL(sales) */ COUNT(*) FROM sales;

  COUNT(*)
----------
    918843

SUMファンクションをNO INMEMORY列であるamount_soldに適用して、述語ではINMEMORY列のみを参照します。

SELECT SUM(amount_sold) AS revenue 
FROM   sales 
WHERE  time_id >= TO_DATE('1994-01-01',  'YYYY-MM-DD') 
AND    prod_id BETWEEN 30 and 40
AND    quantity_sold < 2;

   REVENUE
----------
7695555.89

次の実行計画のステップ3は、オプティマイザがインメモリー・ハイブリッド・スキャンを選択したことを示しています。

SH@21c> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);
SQL_ID  6nz5k0y07akx8, child number 0
-------------------------------------
SELECT SUM(amount_sold) as revenue FROM   sales WHERE  time_id >=
TO_DATE('1994-01-01',  'YYYY-MM-DD') AND    prod_id BETWEEN 30 and 40
AND    quantity_sold < 2

Plan hash value: 3519235612
-------------------------------------------------------------------------------------------
|Id | Operation                             |Name|Rows|Bytes|Cost (%CPU)|Time|Pstart|Pstop|
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT                      |      |    |     |463 (100)|        |   |    |
| 1 |  SORT AGGREGATE                       |      |  1 |  20 |         |        |   |    |
| 2 |   PARTITION RANGE ALL                 |      |196K|3834K|463   (2)|00:00:01| 1 | 28 |
|*3 |    TABLE ACCESS INMEMORY FULL (HYBRID)| SALES|196K|3834K|463   (2)|00:00:01| 1 | 28 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(("PROD_ID"<=40 AND "PROD_ID">=30 AND 
       "TIME_ID">=TO_DATE(' 1994-01-01 00:00:00','syyyy-mm-dd hh24:mi:ss') 
       AND "QUANTITY_SOLD"<2))
IM仮想列

IM仮想列は、式を評価することによってその値が導出されること以外は、他の任意の列と同じです。

IM仮想列の目的

事前に計算されたIM仮想列の値をIM列ストアに格納すると、問合せのパフォーマンスが向上する可能性があります。式には、同じ表からの列、制約、SQL関数およびユーザー定義PL/SQL関数(DETERMINISTICのみ)を含めることができます。IM仮想列に明示的に書き込むことはできません。

仮想列は様々なコンテキストで使用されます。たとえば、INMEMORY空間表に仮想列を追加し、SDO_FILTERなどの演算子を使用すると、空間索引を使用せずにその表を問い合せることができます。

IM仮想列のユーザー・インタフェース

IM列ストアにIM仮想列を移入するには、INMEMORY_VIRTUAL_COLUMNS初期化パラメータを次のいずれかの値に設定します。

  • MANUAL (デフォルト): 表がIM列ストアに対して有効になっている場合、この表で定義されているIM仮想列は、明示的にINMEMORYとして設定されていないかぎり、移入の対象ではありません。

  • ENABLE: 表がIM列ストアに対して有効になっている場合、この表で定義されているすべてのIM仮想列は、明示的にNO INMEMORYとして設定されていないかぎり、移入の対象となります。

    デフォルトでは、IM列ストア内の列の圧縮レベルは、それが格納されている表またはパーティションと同じです。ただし、IM仮想列に対して異なる圧縮レベルが指定されている場合、それは指定された圧縮レベルで移入されます。

ノート:

仮想列またはIM式は、表内で許可されている上限までカウントされます。この上限はデフォルトでは1000ですが、MAX_COLUMNSが有効になっている場合は、移入されるオブジェクトごとに4096列まで拡張できます。

関連項目:

MAX_COLUMNSの値を設定して、列の最大数を変更できます。

IM列ストアにIM仮想列を移入しないように指定するには、この初期化パラメータをDISABLE: INMEMORY_VIRTUAL_COLUMNS = "DISABLE"に設定します。

IM仮想列およびIM式の基礎となる記憶域構造は同じです。ただし、IM式およびIM仮想列は異なるメカニズムで制御されます。

ノート:

  • IM列ストアでは、INMEMORYとマークされている表の仮想列のみが移入されます。

  • IM列ストアにIM仮想列を移入するには、COMPATIBLE初期化パラメータの値が12.1.0以上に設定されている必要があります。

IM全文列

インメモリー全文列は、INMEMORY TEXT句で指定できます。

IM全文列の目的

以前のリリースでは、IM列ストアは、テキスト、XML、JSONなどの非スカラー・ドキュメント・オブジェクトに対する述語をサポートしていませんでした。こうしたタイプには、CLOB列のCONTAINS()など、独自のドメイン固有の述語や投影問合せ構成があります。高速述語評価には、Oracle全文索引、XML検索索引、JSON検索索引などのドメイン索引が必要でした。述語にCONTAINS()またはJSON_TEXTCONTAINS()演算子があるときは、最適化されたインメモリー検索が実行されます。

IM表スキャンでは、スカラーと非スカラーの両方のデータを評価できます。IM列ストアにスカラー列と非スカラー列が両方含まれている場合です。

全文列の仕組み

すべてのドメイン固有のデータ・オブジェクトは、そのドメイン固有の形式でIM列ストアに格納されます。IM全文機能では、次のデータ型がサポートされます。

  • CHAR

  • VARCHAR2

  • CLOB

  • BLOB

  • JSON

以前のリリースでは、CONTAINS()JSON_TEXTCONTAINS()を使用する問合せは、テキスト索引とJSON検索索引でのみ評価されていました。Oracle Database 20以降では、ドキュメントを格納する基礎となる列をINMEMORY TEXTとして指定すると、問合せでSQL述語のそれらの演算子が評価されます。ドメイン固有の索引は、オプションです。

JSON列と非JSON列は、どちらもCTX_DDL.CREATE_POLICYプロシージャによって作成されるカスタム索引付けポリシーをサポートしています。このプロシージャにはCTXAPPロールかCTXSYS.CTX_DDLパッケージに対する実行権限が必要になります。列のデータ型がJSONの場合、その列が次のいずれかを使用するときに、この列のIM全文バージョンでJSON_TEXTCONTAINS()を使用したパス認識検索が可能になります。

  • デフォルト・ポリシー

  • JSON_ENABLED属性がTRUEに設定されているPATH_SECTION_GROUPによるカスタム・ポリシー

全文列用のユーザー・インタフェース

CREATE TABLEALTER TABLEは、どちらもINMEMORY TEXT句をサポートしています。PRIORITY句は、IM全文列の移入にも標準インメモリー列と同じ効果があります。デフォルトの優先度はNONEです。MEMCOMPRESS句は、INMEMORY TEXTでは無効です。

表5-3 INMEMORY TEXT句

構文 説明

INMEMORY TEXT (col1, col2, …)

IM全文として有効にする列のリストを指定します。列のタイプはCHARVARCHAR2CLOBBLOBまたはJSONであることが必要です。JSON列では、自動的にJSON_TEXTCONTAINS()が有効化されます。

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

カスタム索引付けポリシーとともにIM全文として有効にする列のリストを指定します。列のタイプはCHARVARCHAR2CLOBBLOBであることが必要です。

表5-4 IM全文に関連する初期化パラメータ

構文 説明

MAX_STRING_SIZE

SQL内のVARCHAR2NVARCHAR2およびRAWデータ型の最大サイズを制御します。IM全文列では、MAX_STRING_SIZEEXTENDEDを設定する必要があるため、バイト制限を32767に増やします。

INMEMORY_VIRTUAL_COLUMNS

IM仮想列として格納されるユーザー定義の仮想列を制御します。IM全文列では、INMEMORY_VIRTUAL_COLUMNSENABLEを設定する必要があります。

関連項目:

IM仮想列の有効化

IM仮想列により、計算の繰返しをなくすことで、問合せのパフォーマンスが向上します。また、データベースはSIMDベクター処理などの手法を使用してIM仮想列をスキャンおよびフィルタリングできます。

前提条件

IM仮想列を有効にするには、次の条件を満たしている必要があります。

IM仮想列を有効にするには:

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

  2. INMEMORY_VIRTUAL_COLUMNS初期化パラメータをENABLEに設定するか、特定の仮想列をIM列ストアに対して有効にします。

例5-3 IM列ストアに対する仮想列の有効化

この例では、SYSTEMとしてデータベースにログインしています。IM列ストアは有効化されていますが、仮想列の移入は現在無効化されています。

SQL> SHOW PARAMETER INMEMORY_SIZE

NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
inmemory_size                        big integer 200M

SQL> SHOW PARAMETER INMEMORY_VIRTUAL_COLUMNS

NAME                                 TYPE        VALUE
------------------------------------ ----------- -------
inmemory_virtual_columns             string      DISABLE

仮想列をhr.employees表に追加してから、その表がINMEMORYであると指定します。

SQL> ALTER TABLE hr.employees ADD (weekly_sal AS (ROUND(salary*12/52,2)));

Table altered.

SQL> ALTER TABLE hr.employees INMEMORY;

Table altered.

この段階では、weekly_salは移入の対象ではありませんが、hr.employees内の非仮想列は移入の対象となっています。次の文により、weekly_sal、およびhr.employees内の他の仮想列が移入されるようになります。

SQL> ALTER SYSTEM SET INMEMORY_VIRTUAL_COLUMNS=ENABLE SCOPE=BOTH;

System altered.

SCOPE=SPFILEを使用することもできますが、その場合、変更は次にデータベースを再起動するまで有効になりません。SCOPE=BOTHを使用すると、変更はすぐに行われます。再起動は不要です。

例5-4 IM列ストアに対する特定のIM仮想列の有効化

この例では、INMEMORY_VIRTUAL_COLUMNS初期化パラメータがMANUALに設定され、IM列ストアにIM仮想列を明示的に追加する必要があることを前提としています。この例では、最初にhr.admin_emp表を作成します。

CREATE TABLE hr.admin_emp (
      empno      NUMBER(5) PRIMARY KEY,
      ename      VARCHAR2(15) NOT NULL,
      job        VARCHAR2(10),
      sal        NUMBER(7,2),
      hrly_rate  NUMBER(7,2) GENERATED ALWAYS AS (sal/2080),
      deptno     NUMBER(3) NOT NULL)
   INMEMORY;

この段階では、hrly_rate仮想列は、移入の対象ではありません。次の文では、その仮想列がINMEMORYとして明示的に指定されます。

ALTER TABLE hr.admin_emp INMEMORY(hrly_rate);

例5-5 インメモリー空間表への仮想列の追加

この例では、位置データを含むが、最初は空間ジオメトリ列を含まない表を作成します。次に、空間ジオメトリ列を追加します。既存の緯度および経度の座標に基づいてジオメトリ・オブジェクトを移入するように表を更新します。空間メタデータも更新します。最後に、表をINMEMORYに変換し、空間列をINMEMORY SPATIALとして指定してメモリー内空間索引を作成します。

  1. サンプル表city_pointsを作成し、各都市内またはその近くの場所に一連の座標(latitudeおよびlongitude)を挿入します。

    CREATE TABLE city_points (
      city_id NUMBER PRIMARY KEY,
      city_name VARCHAR2(25),
      latitude NUMBER,
      longitude NUMBER);
    
    INSERT INTO city_points (city_id, city_name, latitude, longitude)
      VALUES (1, 'Boston', 42.207905, -71.015625);
    INSERT INTO city_points (city_id, city_name, latitude, longitude)
      VALUES (2, 'Raleigh', 35.634679, -78.618164);
    INSERT INTO city_points (city_id, city_name, latitude, longitude)
      VALUES (3, 'San Francisco', 37.661791, -122.453613);
    INSERT INTO city_points (city_id, city_name, latitude, longitude)
      VALUES (4, 'Memphis', 35.097140, -90.065918);
    
  2. 空間ジオメトリ列をcity_points表に追加します。
    ALTER TABLE city_points ADD (shape SDO_GEOMETRY);
  3. 挿入した位置座標に基づいて、ジオメトリ・オブジェクトを新しい列に移入します。
    UPDATE city_points SET shape = 
      SDO_GEOMETRY(
        2001,
        8307,
        SDO_POINT_TYPE(LONGITUDE, LATITUDE, NULL),
        NULL,
        NULL
       );
  4. user_sdo_geom_metadataビューで空間メタデータを更新します。
    INSERT INTO user_sdo_geom_metadata VALUES (
      'city_points',
      'SHAPE', 
      SDO_DIM_ARRAY(
        SDO_DIM_ELEMENT('Longitude',-180,180,0.5), 
        SDO_DIM_ELEMENT('Latitude',-90,90,0.5)
      ), 
      8307
    );
    commit;
  5. city_points表を変更して、IM列ストアへの移入の候補にします。表をINMEMORYとして指定します。この表にはshape空間ジオメトリ列が含まれるため、INMEMORY SPATIALキーワードも含めます。
    ALTER TABLE city_points INMEMORY PRIORITY high INMEMORY SPATIAL (shape);

    その後、DBMS_INMEMORY.POPULATEを使用してIM列ストアにcity_points表を移入できます。

    EXEC DBMS_INMEMORY.POPULATE('chicago','city_points');

ノート:

仮想列は、空間ジオメトリ列の一部として作成されます。これは、In-Memory機能とは関係ありません。INMEMORY SPATIALキーワードを使用すると、IME列が1つ以上作成されます。

関連項目:

Spatial and Graph開発者ガイド。ここで、空間概念のより詳細な説明で同じ例が使用されています。

例5-6 空間ダイジェストの使用(IM列ストアのMIN/MAX値IME)

SELECT city_name 
FROM city_points c 
where 
 sdo_filter(c.shape, 
            sdo_geometry(2001,8307,sdo_point_type(-122.453613,37.661791,null),null,null)
           ) = 'TRUE'; 

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());

例5-7 空間を拡張しないDBIMの使用

SELECT * FROM city_points c where c.shape.sdo_point.x = -122.453613; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());

例5-8 仮想列の作成の検証

col table_name format a20
col column_name format a30
col data_type format a20
col data_default format a30 word_wrapped;
select
 table_name, column_name, data_type, DATA_LENGTH, DATA_DEFAULT
from user_tab_cols 
 where column_name like 'SYS%';

SELECT * FROM city_points c;
クリーン・アップする場合は、関連するメタデータを削除してから、city_pointsサンプル表を削除してパージします。
delete from user_sdo_geom_metadata where table_name = 'CITY_POINTS'; drop table city_points purge; 

IM全文列の有効化

IM全文列を有効にするには、CREATE TABLEおよびALTER TABLE文でINMEMORY TEXT句を指定します。

前提条件

IM全文列を有効にするには、次の条件を満たしている必要があります。

  • IM列ストアがデータベースに対して必ず有効化されていること。

    CDBまたはPDBに対するIM列ストアの有効化を参照してください。

  • IM仮想列を有効にする必要があります。

    IM仮想列の有効化を参照してください。

  • MAX_STRING_SIZE初期化パラメータはEXTENDEDに設定する必要があります。

  • カスタム索引付けポリシーを指定する場合は、そのポリシーが必ず存在していること。

    ポリシーは、CTX_DDL.CREATE_POLICYで作成できます。このプロシージャには、CTXAPPロールまたはCTXSYS.CTX_DDLパッケージに対するEXECUTE権限が必要です。

IM全文列を有効にするには:

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

  2. 次のいずれかの形式を使用して、CREATE TABLE文またはALTER TABLE文でINMEMORY TEXT句を指定します。

    • INMEMORY TEXT (col1, col2, …)

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

例5-9 IM全文列の有効化

この例では、CTXAPPロールを持つユーザー・アカウントbiblioでログインします。2つのIM全文検索列text_docjson_docを保持する表を作成します。


CREATE TABLE books (id NUMBER, createTime DATE, text_doc CLOB, json_doc JSON) 
   INMEMORY TEXT(text_doc, json_doc);

テキスト検索用のカスタム・ポリシーを作成して、次のようにtext_doc列に適用します。

EXEC CTX_DDL.CREATE_POLICY('book_search_policy'); 
ALTER TABLE books INMEMORY TEXT (text_doc USING 'book_search_policy');

JSONデータ型を使用するbooks.json_doc列は、デフォルトのポリシーを使用する点に注意してください。

例5-10 INMEMORY TEXT列に対するカスタム・ポリシーの置換

この例では、2つのIM全文検索列text_docjson_docによって、表booksが有効化されています。text_doc列には、カスタム・ポリシーbook_search_policyを使用します。既存のポリシーをbook_search_policy2というポリシーに置き換えることが目的です。次のように、NO INMEMORY属性を適用してから、INMEMORYを適用する必要があります。

ALTER TABLE books NO INMEMORY TEXT(text_doc);
ALTER TABLE books INMEMORY TEXT (text_doc USING 'book_search_policy2');

関連項目:

IM列ストアに対する列のサブセットの有効化

この例では、IM列ストアに対してoe.product_information表のすべての列を有効にしますが、weight_classおよびcatalog_urlは例外です。

また、次の文は、IM列ストアに対して有効な列に、別のIM列ストア圧縮方法を指定します。

ALTER TABLE oe.product_information  
   INMEMORY MEMCOMPRESS FOR QUERY (
      product_id, product_name, category_id, supplier_id, min_price)
   INMEMORY MEMCOMPRESS FOR CAPACITY HIGH (
      product_description, warranty_period, product_status, list_price)
   NO INMEMORY (
      weight_class, catalog_url);

次の点に注意してください。

  • product_idproduct_namecategory_id supplier_idおよびmin_priceの各列は、MEMCOMPRESS FOR QUERY圧縮方法を使用してIM列ストアに対して有効になります。

  • product_descriptionwarranty_periodproduct_statusおよびlist_priceの各列は、MEMCOMPRESS FOR CAPACITY HIGH圧縮方法を使用してIM列ストアに対して有効になります

  • weight_class列およびcatalog_url列は、IM列ストアに対して有効になりません。したがって、SELECTリストと述語のいずれかでこれら2つの列を参照する問合せは、IM列ストアではなく行ストアを使用する必要があります。

  • 表では、PRIORITY句のデフォルトであるPRIORITY NONEが使用されます。

ノート:

優先度レベル設定は、表全体またはパーティションに適用する必要があります。表の列のサブセットごとに異なるIM列ストアの優先度レベルを指定することはできません。

データベース・オブジェクトに対して定義されている、選択された列圧縮レベルを判断するには、次の例で示すようにV$IM_COLUMN_LEVELビューを問い合せます。

COL TABLE_NAME FORMAT a20
COL COLUMN_NAME FORMAT a20

SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION 
FROM   V$IM_COLUMN_LEVEL 
WHERE  TABLE_NAME = 'PRODUCT_INFORMATION'
ORDER BY COLUMN_NAME;

TABLE_NAME           COLUMN_NAME          INMEMORY_COMPRESSION
-------------------- -------------------- --------------------------
PRODUCT_INFORMATION  CATALOG_URL          NO INMEMORY
PRODUCT_INFORMATION  CATEGORY_ID          FOR QUERY LOW
PRODUCT_INFORMATION  LIST_PRICE           FOR CAPACITY HIGH
PRODUCT_INFORMATION  MIN_PRICE            FOR QUERY LOW
PRODUCT_INFORMATION  PRODUCT_DESCRIPTION  FOR CAPACITY HIGH
PRODUCT_INFORMATION  PRODUCT_ID           FOR QUERY LOW
PRODUCT_INFORMATION  PRODUCT_NAME         FOR QUERY LOW
PRODUCT_INFORMATION  PRODUCT_STATUS       FOR CAPACITY HIGH
PRODUCT_INFORMATION  SUPPLIER_ID          FOR QUERY LOW
PRODUCT_INFORMATION  WARRANTY_PERIOD      FOR CAPACITY HIGH
PRODUCT_INFORMATION  WEIGHT_CLASS         NO INMEMORY

関連項目:

NO INMEMORY表でのINMEMORY列属性の指定

INMEMORY句は、INMEMORYとしてまだマークされていないオブジェクトの列レベルで指定できます。

INMEMORY句を列レベルで指定した場合、指定した列の属性がデータベースに記録されます。表がNO INMEMORY (デフォルト)の場合、表またはパーティションがINMEMORYとして指定されるまで、列レベルの属性は、表を問い合せる方法には影響しません。表自体をNO INMEMORYとしてマークした場合は、データベースにより、既存の列レベル属性が削除されます。

この例での目的は、パーティション表内の列c3がIM列ストアに移入されないようにすることです。次のステップを実行します。

  1. 次のように、パーティション表tを作成します。

    CREATE TABLE t (c1 NUMBER, c2 NUMBER, c3 NUMBER) 
      NO INMEMORY -- this clause specifies the table itself as NO INMEMORY
      PARTITION BY LIST (c1) 
        ( PARTITION p1 VALUES (0), 
          PARTITION p2 VALUES (1), 
          PARTITION p3 VALUES (2) );

    tNO INMEMORYです。この表は、列c1上のリストによってパーティション化されており、p1p2およびp3という3つのパーティションを含んでいます。

  2. 表内の列の圧縮を問い合せます(出力例が含まれています)。

    COL TABLE_NAME FORMAT a20
    COL COLUMN_NAME FORMAT a20
    
    SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION
    FROM   V$IM_COLUMN_LEVEL
    WHERE  TABLE_NAME = 'T'
    ORDER BY COLUMN_NAME;
    
    no rows selected

    出力で示されているように、列レベルのINMEMORY属性は設定されていません。

  3. c3が移入されないようにするには、NO INMEMORY属性を列c3に適用します。

    ALTER TABLE t NO INMEMORY (c3);
  4. 表内の列の圧縮を問い合せます(出力例が含まれています)。

    SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION
    FROM   V$IM_COLUMN_LEVEL
    WHERE  TABLE_NAME = 'T'
    ORDER BY COLUMN_NAME;
    
    TABLE_NAME           COLUMN_NAME          INMEMORY_COMPRESSION
    -------------------- -------------------- --------------------
    T                    C1                   DEFAULT
    T                    C2                   DEFAULT
    T                    C3                   NO INMEMORY

    データベースでは、c3NO INMEMORY属性が記録されています。他の列では、デフォルトの圧縮が使用されます。

  5. パーティションp3INMEMORYとして指定します。

    ALTER TABLE t 
      MODIFY PARTITION p3 
        INMEMORY PRIORITY CRITICAL;

    c3は前にNO INMEMORYとして指定されているため、パーティションp3の最初の移入には、列c3は含まれません。

  6. 表全体をINMEMORYとして指定します。

    ALTER TABLE t INMEMORY;
  7. 表内の列の圧縮を問い合せます(出力例が含まれています)。

    SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION
    FROM   V$IM_COLUMN_LEVEL
    WHERE  TABLE_NAME = 'T'
    ORDER BY COLUMN_NAME;
    
    TABLE_NAME           COLUMN_NAME          INMEMORY_COMPRESSION
    -------------------- -------------------- --------------------------
    T                    C1                   DEFAULT
    T                    C2                   DEFAULT
    T                    C3                   NO INMEMORY

    データベースでは、列c3NO INMEMORY設定が保持されています。他の列では、デフォルトの圧縮が使用されます。

  8. 異なる圧縮レベルを列c1およびc2に適用します。
    ALTER TABLE t 
      INMEMORY MEMCOMPRESS FOR CAPACITY HIGH (c1) 
      INMEMORY MEMCOMPRESS FOR CAPACITY LOW (c2);
  9. 表内の列の圧縮を問い合せます(出力例が含まれています)。

    SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION
    FROM   V$IM_COLUMN_LEVEL
    WHERE  TABLE_NAME = 'T'
    ORDER BY COLUMN_NAME;
    
    TABLE_NAME           COLUMN_NAME          INMEMORY_COMPRESSION
    -------------------- -------------------- --------------------------
    T                    C1                   FOR CAPACITY HIGH
    T                    C2                   FOR CAPACITY LOW
    T                    C3                   NO INMEMORY

    これで、各列に異なる圧縮レベルが設定されました。

  10. 表全体をNO INMEMORYとして指定します。

    ALTER TABLE t NO INMEMORY;
  11. 表内の列の圧縮を問い合せます(出力例が含まれています)。

    SELECT TABLE_NAME, COLUMN_NAME, INMEMORY_COMPRESSION
    FROM   V$IM_COLUMN_LEVEL
    WHERE  TABLE_NAME = 'T'
    ORDER BY COLUMN_NAME;
    
    no rows selected

    表全体がNO INMEMORYとして指定されたため、データベースにより、列レベルのすべてのINMEMORY属性が削除されました。

関連項目:

ALTER TABLEの構文およびセマンティクスは、『Oracle Database SQL言語リファレンス』を参照してください。

INMEMORY(ALL)およびNO INMEMORY(ALL)副句

表のすべての列を含めるか除外する場合は、INMEMORY(ALL)またはNO INMEMORY(ALL)を使用できます。

NO INMEMORY(ALL)

Oracle Database 23aiでは、INMEMORY(ALL)およびNO IMEMORY(ALL)の後に包含リストまたは除外リストを指定して、インメモリーを有効または無効にする列を指定できます。これにより、列の非常に長い文字列を使用する必要が減り、インメモリーが有効な表の構成が以前のリリースよりも簡単になります。

NO INMEMORY(ALL)は、すべての列をNO INMEMORYとしてマークします。

これらの副句が導入される前のCREATE TABLE文またはALTER TABLE文では、インメモリー列ストアに表の列のサブセットのみを追加する場合に、表INMEMORYを宣言してから、NO INMEMORYの後にすべての列のリストを指定する必要があります。この除外リストは長くなる場合があります。

NO INMEMORY(ALL)句を使用すると、すべての列をNO INMEMORYに設定してから、INMEMORYを指定して、インメモリー列ストアに追加する列のサブセットの包含リストを指定できます。

たとえば、次の表fooは数十個の列で作成されていますが、最初の3列のみをインメモリー列ストアに追加するとします:

CREATE TABLE foo ... NO INMEMORY(ALL) INMEMORY(c1, C2, C3);

INMEMORY(ALL)

INMEMORY(ALL)は、すべての列をINMEMORYとしてマークします。その後、除外リストを追加することもできます。

表fooのほとんどの列をインメモリー列ストアに追加するが、列のサブセットを除外する必要があるとします。この場合、INMEMORY(ALL)を指定してから、この句の後にNO INMEMORY句および除外リストを指定できます:

CREATE TABLE foo ... INMEMORY(ALL) NO INMEMORY(c1, C2, C3);

IM列ストアに対する表領域の有効化および無効化

IM列ストアに対する表領域を有効化または無効化できます。

INMEMORY句を指定したCREATE TABLESPACE文を使用して表領域を作成する際に、IM列ストアに対して表領域を有効にします。また、INMEMORY句を指定したALTER TABLESPACE文を使用して、IM列ストアに対して有効になるように表領域を変更できます。

IM列ストアに対して表領域を無効にするには、CREATE TABLESPACE文またはALTER TABLESPACE文にNO INMEMORY句を指定します。

IM列ストアに対して表領域が有効になっている場合、表領域内の表およびマテリアライズド・ビューはすべて、デフォルトでIM列ストアに対して有効になります。INMEMORY句は、表、マテリアライズド・ビューおよび表領域の場合と同じです。DEFAULT記憶域句は、IM列ストアに対して表領域を有効にする場合はINMEMORY句の前に、IM列ストアに対して表領域を無効にする場合はNO INMEMORY句の前に必要です。

IM列ストアに対して表領域が有効になっている場合、表領域内の個々の表およびマテリアライズド・ビューに異なるインメモリー設定を指定でき、個々のデータベース・オブジェクトの設定は表領域の設定を上書きします。たとえば、メモリーにデータを移入するために表領域がPRIORITY LOWに設定されているのに対し、表領域内の表がPRIORITY HIGHに設定されている場合、その表ではPRIORITY HIGHを使用します。

前提条件

IM列ストアがデータベースに対して有効になっていることを確認します。CDBまたはPDBに対するIM列ストアの有効化を参照してください。

IM列ストアに対する表領域を有効化または無効化にします。

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

  2. INMEMORY句またはNO INMEMORY句を指定して、CREATE TABLESPACEまたはALTER TABLESPACE文を実行します。

例5-11 表領域の作成とIM列ストアに対する有効化

次の例では、users01表領域を作成し、IM列ストアに対して有効にします。

CREATE TABLESPACE users01 
   DATAFILE 'users01.dbf' SIZE 40M 
   ONLINE
   DEFAULT INMEMORY;

この例では、INMEMORY句にデフォルトを使用しています。したがって、MEMCOMPRESS FOR QUERYおよびPRIORITY NONEが使用されます。

例5-12 表領域の変更とIM列ストアに対する有効化

次の例では、IM列ストアに対して有効になるようにusers01表領域を変更し、表領域内のデータベース・オブジェクトに対してFOR CAPACITY HIGH圧縮を指定し、メモリーにデータを移入するためにPRIORITY LOWを指定します。

ALTER TABLESPACE users01 DEFAULT INMEMORY 
   MEMCOMPRESS FOR CAPACITY HIGH 
   PRIORITY LOW;

IM列ストアに対するマテリアライズド・ビューの有効化および無効化

IM列ストアに対してマテリアライズド・ビューを有効および無効にすることができます。

IM列ストアに対してマテリアライズド・ビューを有効にするには、CREATE MATERIALIZED VIEWまたはALTER MATERIALIZED VIEW文でINMEMORY句を使用します。IM列ストアに対してマテリアライズド・ビューを無効にするには、CREATE MATERIALIZED VIEWまたはALTER MATERIALIZED VIEW文でNO INMEMORY句を使用します。

前提条件

IM列ストアがデータベースに対して有効になっていることを確認します。CDBまたはPDBに対するIM列ストアの有効化を参照してください。

IM列ストアに対してマテリアライズド・ビューを有効または無効にするには:

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

  2. INMEMORY句またはNO INMEMORY句を指定して、CREATE MATERIALIZED VIEWまたはALTER MATERIALIZED VIEW文を実行します。

例5-13 マテリアライズド・ビューの作成とIM列ストアに対する有効化

次の文では、oe.prod_info_mvマテリアライズド・ビューを作成し、IM列ストアに対して有効にします。

CREATE MATERIALIZED VIEW oe.prod_info_mv INMEMORY 
  AS SELECT * FROM oe.product_information;

この例では、INMEMORY句のデフォルトであるMEMCOMPRESS FOR QUERY LOWおよびPRIORITY NONEを使用します。

例5-14 HIGHデータ移入優先度を指定したIM列ストアに対するマテリアライズド・ビューの有効化

次の文では、IM列ストアに対してoe.prod_info_mvマテリアライズド・ビューを有効にします。

ALTER MATERIALIZED VIEW oe.prod_info_mv INMEMORY PRIORITY HIGH;

この例では、デフォルトの圧縮であるMEMCOMPRESS FOR QUERY LOWを使用します。

関連項目:

CREATEまたはALTER MATERIALIZED VIEW文についてさらに学習するには、『Oracle Database SQL言語リファレンス』を参照してください。