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

この章では、圧縮や優先順位のオプションの設定を含め、IM列ストアへの移入に対してオブジェクトを有効および無効にする方法を説明します。

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

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

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

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

デフォルトでは、オブジェクトにNO INMEMORY属性が暗黙的に含まれており、これはオブジェクトがIM列ストアへの移入の対象ではないことを意味します。

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

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

4.1.2 インメモリー移入はどのように機能するか

データベース・インスタンス起動時またはINMEMORYオブジェクトへのアクセス時のどちらかにデータベースによってオブジェクトがIM列ストアに移入されるよう指定できます。

移入アルゴリズムは、単一インスタンスまたはOracle RACのどちらを使用するかによっても異なります。

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

4.1.2.1 インメモリー移入の優先順位付け

DDL文には、移入キューをより細かく制御できるようにするINMEMORY PRIORITY副句が含まれています。

ノート:

INMEMORY PRIORITY副句は、移入の速度ではなく、移入の優先順位を制御します。

優先度レベル設定は、別々の列サブセットではなく、全体の表、パーティションまたはサブパーティションに適用されます。オブジェクト上でINMEMORY属性を設定することは、このオブジェクトがIM列ストアへの移入の候補であることを意味します。データベースでそのオブジェクトがすぐに移入されることを意味するわけではありません。

ノート:

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

Oracle Databaseでは、次のように優先順位付けが管理されます。

  • オンデマンド移入

    デフォルトでは、INMEMORY PRIORITYパラメータはNONEに設定されています。この場合、データベースでは、オブジェクトは表の全体スキャンを通じてアクセスされるときのみ移入されます。オブジェクトがアクセスされることがないか、索引スキャンまたはROWIDによるフェッチを通じてしかアクセスされない場合は、移入が起こることはありません。

  • 優先度ベース移入

    PRIORITYNONE以外の値に設定されている場合、Oracle databaseでは、内部的に管理される優先順位キーを使用して、オブジェクトが自動的に移入されます。この場合、全体スキャンは、移入に必要な条件ではありません。データベースでは、次のことが実行されます。

    • データベース・インスタンスの再起動後に、列データをIM列ストアに自動的に移入します

    • 指定された優先度レベルに基づいて、INMEMORYオブジェクトの移入を問い合せます

      たとえば、INMEMORY PRIORITY CRITICALで変更された表はINMEMORY PRIORITY HIGHで変更された表よりも優先され、この表もまた、INMEMORY PRIORITY LOWで変更された表よりも優先されます。IM列ストアに十分な領域がない場合、Oracle Databaseは領域が使用可能になるまで追加オブジェクトを移入しません。

    • オブジェクトに対する変更がIM列ストアで記録されるまで、ALTER TABLEまたはALTER MATERIALIZED VIEW文からの返答を待機します

セグメントがIM列ストアに移入された後、データベースでそれが除去されるのは、そのセグメントが削除または移動されるか、NO INMEMORY属性で更新されるときのみです。セグメントは手動またはADOポリシーによって除去できます。

例4-1 IM列ストアへのオブジェクトの移入

この例を完了する前に、IM列ストアをデータベースに対して有効にする必要があります。

  1. データベースに管理者としてログインしてから、次のようにcustomers表を問い合せます。

    SELECT cust_id, cust_last_name, cust_first_name 
    FROM   sh.customers 
    WHERE  cust_city = 'Hyderabad' 
    AND    cust_income_level LIKE 'C%' 
    AND    cust_year_of_birth > 1960;
  2. 問合せの実行計画を表示します。

    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'+ALLSTATS'));
    SQL_ID  frgk9dbaftmm9, child number 0
    -------------------------------------
    SELECT cust_id, cust_last_name, cust_first_name FROM   sh.customers
    WHERE  cust_city = 'Hyderabad' AND    cust_income_level LIKE 'C%' AND
     cust_year_of_birth > 1960
    
    Plan hash value: 2008213504
    
    -------------------------------------------------------------------------------
    | Id| Operation         | Name      |Starts|E-Rows|A-Rows|   A-Time   |Buffers|
    -------------------------------------------------------------------------------
    |  0| SELECT STATEMENT  |           |     1|      |    6 |00:00:00.01 |   1523|
    |* 1|  TABLE ACCESS FULL| CUSTOMERS |     1|    6 |    6 |00:00:00.01 |   1523|
    -------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter(("CUST_CITY"='Hyderabad' AND "CUST_YEAR_OF_BIRTH">1960 AND
                  "CUST_INCOME_LEVEL" LIKE 'C%'))
    
  3. sh.customers表をIM列ストアへの移入のために有効にします。

    ALTER TABLE sh.customers INMEMORY;

    上の文では、デフォルトの優先順位であるNONEが使用されます。優先順位なしでオブジェクトを移入するには、全体スキャンが必要となります。

  4. sh.customers表からのデータがIM列ストアに移入されているかどうかを判断するには、次の問合せを実行します(出力例が含まれています)。

    SELECT SEGMENT_NAME, POPULATE_STATUS 
    FROM   V$IM_SEGMENTS 
    WHERE  SEGMENT_NAME = 'CUSTOMERS';
    
    no rows selected
    

    この場合、sh.customers表はまだスキャンされていないため、IM列ストアに移入されているセグメントはありません。

  5. ステップ1と同じ文を使用してsh.customersを問い合せます。

    SELECT cust_id, cust_last_name, cust_first_name 
    FROM   sh.customers 
    WHERE  cust_city = 'Hyderabad' 
    AND    cust_income_level LIKE 'C%' 
    AND    cust_year_of_birth > 1960;
    
  6. カーソルの問合せでは、データベースで全体スキャンを実行しIM列ストアにアクセスしたことが示されます。

    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'+ALLSTATS'));
    SQL_ID  frgk9dbaftmm9, child number 0
    -------------------------------------
    SELECT cust_id, cust_last_name, cust_first_name FROM   sh.customers
    WHERE  cust_city = 'Hyderabad' AND    cust_income_level LIKE 'C%' AND
     cust_year_of_birth > 1960
    
    Plan hash value: 2008213504
    
    ---------------------------------------------------------------------------------
    | Id| Operation           | Name            |Starts|E-Rows|A-Rows|A-Time|Buffers|
    ---------------------------------------------------------------------------------
    |  0| SELECT STATEMENT           |           |    1|     | 6 |00:00:00.02| 1523 |
    |* 1|  TABLE ACCESS INMEMORY FULL| CUSTOMERS |    1|    6| 6 |00:00:00.02| 1523 |
    ---------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - inmemory(("CUST_CITY"='Hyderabad' AND "CUST_YEAR_OF_BIRTH">1960 AND
                  "CUST_INCOME_LEVEL" LIKE 'C%'))
           filter(("CUST_CITY"='Hyderabad' AND "CUST_YEAR_OF_BIRTH">1960 AND
                  "CUST_INCOME_LEVEL" LIKE 'C%'))
    
  7. V$IM_SEGMENTSを再度問い合せます(出力例が含まれています)。

    COL SEGMENT_NAME FORMAT a20
    
    SELECT SEGMENT_NAME, POPULATE_STATUS 
    FROM   V$IM_SEGMENTS 
    WHERE  SEGMENT_NAME = 'CUSTOMERS';
    
    SEGMENT_NAME         POPULATE_STATUS
    -------------------- ---------------
    CUSTOMERS            COMPLETED

    POPULATE_STATUS内の値COMPLETEDは、表がIM列ストアに移入されていることを意味します。

  8. DBA_FEATURE_USAGE_STATISTICSビューでは、データベースでIM列ストアを使用して結果を取得したことを確認します。
    COL NAME FORMAT a25
    SELECT ul.NAME, ul.DETECTED_USAGES 
    FROM   DBA_FEATURE_USAGE_STATISTICS ul 
    WHERE  ul.VERSION= (SELECT MAX(u2.VERSION) 
                        FROM   DBA_FEATURE_USAGE_STATISTICS u2 
                        WHERE  u2.NAME = ul.NAME 
                        AND    ul.NAME LIKE '%Column Store%');
    
    NAME                      DETECTED_USAGES
    ------------------------- ---------------
    In-Memory Column Store    1
    

関連項目:

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

INMEMORY PRIORITY句について学習するには、『Oracle Database SQL言語リファレンス』を参照

4.1.2.2 バックグラウンド・プロセスによるIMCUの移入方法

移入中、データベースは、行形式でディスクからデータを読み取り、列を作成するために行をピボットし、インメモリー圧縮ユニット(IMCU)にデータを圧縮します。

ワーカー・プロセス(Wnnn)は、IM列ストアにデータを移入します。各ワーカー・プロセスは、オブジェクトのデータベース・ブロックのサブセットで動作します。移入は、データを同時に圧縮して列形式に変換する、ストリーミング・メカニズムです。

INMEMORY_MAX_POPULATE_SERVERS初期化パラメータにより、IM列ストアの移入に使用するワーカー・プロセスの最大数を指定します。デフォルト設定は、CPU_COUNTの2分の1です。このパラメータは環境に適した値に設定します。ワーカー・プロセスの数を増加すると移入は高速化しますが、より多くのCPUリソースが使用されます。ワーカー・プロセスの数を削減すると、移入が低速化し、これによりCPUオーバーヘッドは低減します。

ノート:

INMEMORY_MAX_POPULATE_SERVERS0に設定されている場合、移入は無効化されます。

関連項目:

INMEMORY_MAX_POPULATE_SERVERS初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。

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

INMEMORY句をDDL文で使用して、IM列ストアへの移入の対象となるオブジェクトを指定します。表領域、表(内部および外部)、パーティションおよびマテリアライズド・ビューを使用可能にできます。

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

4.1.3.1 INMEMORY副句

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

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

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

  • 索引

  • 索引構成表

  • ハッシュ・クラスタ

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

4.1.3.1.1 インメモリー表

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

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

パーティション表の場合、IM列ストア内のパーティション(すべてまたは一部)を移入できます。デフォルトでは、パーティション表内のすべてのパーティションはINMEMORY属性を継承します。内部パーティションと外部パーティションの両方を含むハイブリッド・パーティション表の場合、内部パーティションのみがINMEMORY属性を継承します。

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

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

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

    ノート:

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

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

  • 拡張データ型の列

例4-2 表の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

関連項目:

4.1.3.1.2 インメモリー外部表

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

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

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

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

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

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

パーティション化されたインメモリー外部表の制限

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

  • column句、distribute句およびpriority句を含む、外部表の一部のINMEMORY副句は有効ではありません。

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

  • インメモリー外部表では、パーティション化はサポートされていません。内部パーティションと外部パーティションの両方を含むハイブリッド・パーティション表の場合は、内部パーティションのみ(外部パーティションではない)がINMEMORY属性をサポートします。

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

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

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

ノート:

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

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

関連項目:

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

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

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

関連項目:

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

4.1.3.1.4 インメモリー表領域

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

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

ノート:

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

関連項目:

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

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

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

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

ビデオ:

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

表4-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列ストアに対して有効になっている小規模データベース・オブジェクトは、移入されないことがあります。

関連項目:

4.1.3.3 IM列ストアの圧縮方法

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

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

ビデオ:

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

次の表に、IM列ストアでサポートされているデータ圧縮方法をまとめます。

表4-2 IM列ストアの圧縮方法

CREATE/ALTERの構文 説明

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句が指定されている場合またはLOWまたはHIGHのいずれかを指定せずにMEMCOMPRESS FOR QUERYが指定されている場合のデフォルトです。

ノート: INMEMORY_FORCE初期化パラメータにBASE_LEVELが設定されている場合は、INMEMORYオブジェクトおよび列でQUERY LOW圧縮が自動的に使用されます。データ・ディクショナリ・ビューには既存の圧縮設定が引き続き表示される場合がありますが、ベース・レベルでは常にオブジェクトおよび列が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列ストア・データを最も大きく圧縮します。

SQL文では、MEMCOMPRESSキーワードの前にINMEMORYキーワードがある必要があります。

関連項目:

4.1.3.4 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パッケージおよびタイプ・リファレンス』を参照してください。

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

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

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

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

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

前提条件

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

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

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

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

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

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

前提条件

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

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

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

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

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

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

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

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

この例では、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はキーワードとしても解釈されますが、エラーが発生します。
4.2.3.2インメモリー・パーティションを使用した表の作成: 例

この例では、パーティションのサブセットを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列ストアへの移入の対象ではありません。

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

この例では、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が含まれます。

関連項目:

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

この例では、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

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

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

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

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

ALTER TABLE sales INMEMORY;

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

4.2.3.6 インメモリー圧縮を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
4.2.3.7インメモリー優先度をHIGHに設定する方法:例

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

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

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

この例では、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;
4.2.3.9 IM列ストアに対する表の無効化: 例

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

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

ALTER TABLE oe.product_information NO INMEMORY;

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

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

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

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

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

ALTER TABLE product_information NO CELLMEMORY;

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

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

4.3.1 INMEMORY列の有効化について

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

INMEMORYオブジェクトにINMEMORY列がありません

ノート:

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

デフォルトでは、内部オブジェクトにINMEMORY属性がある場合、このオブジェクトのすべての列が、IM列ストアへの移入の対象になります。ただし、INMEMORY表の一部の列はNO INMEMORY属性を持つように指定できます。この場合は、INMEMORY列のみが移入の対象になります。

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

INMEMORY表でNO INMEMORY列を指定すると、重要な結果になります。NO INMEMORY列を参照する問合せは、行ストアを排他的に使用します。たとえば、salesが7列のINMEMORY表で、promo_id列にのみNO INMEMORY属性がある場合、SELECTリストにpromo_idが含まれる問合せは、IM列ストアではなく行ストアからデータを取得します。同様に、promo_idSELECTリストに含まれているかどうかに関係なく、述語がpromo_idを参照する問合せはすべて、行ストアから排他的にデータを取得します。

仮想列

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

ノート:

仮想列またはIM式は、移入されたオブジェクトごとの列の上限である1000個に数えられます。

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

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

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

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

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

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

ノート:

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

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

関連項目:

4.3.2 IM仮想列の有効化

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

前提条件

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

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

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

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

例4-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を使用すると、変更はただちに行われ、再起動は必要ありません。

例4-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);

4.3.3 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

関連項目:

4.3.4 NO INMEMORY表でのINMEMORY列属性の指定: 例

Oracle Database 12cリリース2 (12.2)以降では、まだINMEMORYとして指定されていないオブジェクト上で、列レベルでINMEMORY句を指定できます。

以前のリリースでは、列レベルのINMEMORY句は、INMEMORY表またはパーティションで指定されている場合のみ有効でした。この制限は、表またはパーティションにINMEMORY句を関連付ける前に、列にINMEMORY句を関連付けることはできないことを意味します。

Oracle Database 12cリリース2 (12.2)以降では、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言語リファレンス』を参照してください。

4.4 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列ストアがデータベースに対して有効になっていることを確認します。「データベースに対するIM列ストアの有効化」を参照してください。

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

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

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

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

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

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

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

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

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

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

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

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

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

前提条件

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

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

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

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

例4-7 マテリアライズド・ビューの作成と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を使用します。

例4-8 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言語リファレンス』を参照してください。