6 IM列ストアの手動での移入
データベースはPRIORITY設定がNONEのインメモリー・オブジェクトを自動的に移入しません。これらのオブジェクトに移入するには、SQLまたはPL/SQLを実行する必要があります。
インメモリー・オブジェクトの手動移入について
PRIORITYをNONEに設定してオブジェクトを有効にし、そのオブジェクトをすぐに追加する場合は、問合せまたはPL/SQL呼び出しを使用できます。
手動インメモリー移入の仕組み
移入はオンデマンドまたは優先度ベースのいずれかになります。移入アルゴリズムは、単一インスタンスを使用するかOracle RACを使用するかによっても異なります。
ノート:
-
INMEMORY_AUTOMATIC_LEVELをHIGHに設定すると、Oracle Databaseによって、インメモリー移入に対してすべてのオブジェクトが自動的に有効化され、必要に応じて移入および削除されます。手動による移入は必要ありません。 - 問合せのパフォーマンスが低下しないように、インメモリー移入が完了している場合にのみテキスト列に対して問合せを実行することをお薦めします。
関連項目:
インメモリー移入の優先順位付け
DDL文には、移入キューをより細かく制御できるようにするINMEMORY PRIORITY副句が含まれています。
ノート:
INMEMORY PRIORITY副句は、移入の速度ではなく、移入の優先順位を制御します。
優先度レベル設定は、別々の列サブセットではなく、全体の表、パーティションまたはサブパーティションに適用されます。オブジェクト上でINMEMORY属性を設定することは、このオブジェクトがIM列ストアへの移入の候補であることを意味します。データベースでそのオブジェクトがすぐに移入されることを意味するわけではありません。
ノート:
ディスク上のセグメントが64KB以下の場合、IM列ストアに移入されません。したがって、IM列ストアに対して有効になっている小規模データベース・オブジェクトは、移入されないことがあります。
Oracle Databaseでは、次のように優先順位付けが管理されます。
-
オンデマンド移入
デフォルトでは、
INMEMORY PRIORITYパラメータはNONEに設定されています。この場合、データベースでは、オブジェクトは表の全体スキャンを通じてアクセスされるときのみ移入されます。オブジェクトがアクセスされることがないか、索引スキャンまたはROWIDによるフェッチを通じてしかアクセスされない場合は、移入が起こることはありません。 -
優先度ベース移入
PRIORITYがNONE以外の値に設定されている場合、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ポリシーによって除去できます。
例6-1 IM列ストアへのオブジェクトの移入
この例を完了する前に、IM列ストアをデータベースに対して有効にする必要があります。
-
データベースに管理者としてログインしてから、次のように
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; -
問合せの実行計画を表示します。
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%')) -
sh.customers表をIM列ストアへの移入のために有効にします。ALTER TABLE sh.customers INMEMORY;上の文では、デフォルトの優先順位である
NONEが使用されます。優先順位なしでオブジェクトを移入するには、全体スキャンが必要となります。 -
sh.customers表からのデータがIM列ストアに移入されているかどうかを判断するには、次の問合せを実行します(出力例が含まれています)。SELECT SEGMENT_NAME, POPULATE_STATUS FROM V$IM_SEGMENTS WHERE SEGMENT_NAME = 'CUSTOMERS'; no rows selectedこの場合、
sh.customers表はまだスキャンされていないため、IM列ストアに移入されているセグメントはありません。 -
ステップ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; -
カーソルの問合せでは、データベースで全体スキャンを実行し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%')) -
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 COMPLETEDPOPULATE_STATUS内の値COMPLETEDは、表がIM列ストアに移入されていることを意味します。 -
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
バックグラウンド・プロセスによるIMCUの移入方法
移入中、データベースは、行形式でディスクからデータを読み取り、列を作成するために行をピボットし、インメモリー圧縮ユニット(IMCU)にデータを圧縮します。
ワーカー・プロセス(Wnnn)は、IM列ストアにデータを移入します。各ワーカー・プロセスは、オブジェクトのデータベース・ブロックのサブセットで動作します。移入は、データを同時に圧縮して列形式に変換する、ストリーミング・メカニズムです。
INMEMORY_MAX_POPULATE_SERVERS初期化パラメータにより、IM列ストアの移入に使用するワーカー・プロセスの最大数を指定します。デフォルト設定は、CPU_COUNTの2分の1です。このパラメータは環境に適した値に設定します。ワーカー・プロセスの数を増加すると移入は高速化しますが、より多くのCPUリソースが使用されます。ワーカー・プロセスの数を削減すると、移入が低速化し、これによりCPUオーバーヘッドは低減します。
ノート:
INMEMORY_MAX_POPULATE_SERVERSが0に設定されている場合、移入は無効化されます。
関連項目:
INMEMORY_MAX_POPULATE_SERVERS初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。
手動インメモリー移入のユーザー・インタフェース
全表スキャン、DBMS_INMEMORYプログラム・ユニット、またはDBMS_INMEMORY_ADMIN.POPULATE_WAITのいずれかを使用して、手動でオブジェクトを移入します。
SELECTを使用した移入
表スキャンを強制するSELECT文を発行して、移入を開始できます。
この場合、データベースはオブジェクトの各行を読み取り、それを列形式に変換します。次の文は全表スキャンを保証しません。
SELECT COUNT(*) FROM objectこれは、オプティマイザが索引のスキャンを選択するためです。したがって、次の例に示すように、SELECT COUNT(*)問合せの FULLヒントを使用して全表スキャンを強制することをお薦めします。
SELECT /*+ FULL(customers) NO_PARALLEL(customers) */ COUNT(*) FROM customers;関連項目:
-
FULLヒントについてさらに学習するには、『Oracle Database SQL言語リファレンス』を参照
DBMS_INMEMORY.POPULATEを使用した移入
DBMS_INMEMORY.POPULATEプロシージャは、全体スキャンと同じ結果を出します。
データベースは指定されたオブジェクトの各行を読み取り、行形式から列形式に変換して、IM列ストアに移入します。次のPL/SQLブロックは、customer表の移入を開始します。
BEGIN
DBMS_INMEMORY.POPULATE( schema_name => 'SH', table_name => 'CUSTOMERS');
END;
/関連項目:
-
DBMS_INMEMORYパッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
DBMS_INMEMORY_ADMIN.POPULATE_WAITを使用した移入
DBMS_INMEMORY_ADMIN.POPULATE_WAIT関数は、優先度が指定された優先度以上のすべてのINMEMORYオブジェクトの移入を開始し、移入のステータス値を返します。ユーザー指定の間隔は、値がコール元に戻されるまで関数が待機する最大時間を指定します。
オブジェクトが移入されるかどうかを確認する使用例には、次のものが含まれます。
-
データベースが閉じられたら、管理者のみだけがデータベースにアクセスできるように
STARTUP RESTRICTでデータベースを開き、希望するタイムアウト設定でPOPULATE_WAITを実行します。POPULATE_WAITが、タイムアウトを示す-1を返した場合は、POPULATE_WAITを再実行します。関数が0を返したときに、制限付きセッションを無効にして、管理者以外のユーザーがデータベースに問合せできるようにします。 -
サービスまたはアプリケーション層の手法を使用して、データベース接続をブロックします。分析索引が存在しない場合や、アプリケーションが適切なパフォーマンスを提供するためにIM列ストアに依存している場合は、これらの手法がリソース集中型の問合せを防ぎます。
POPULATE_WAIT関数は、表名を入力として受け入れません。かわりに、ファンクションは指定されたpriority以上のPRIORITY設定(デフォルトはLOW)を使用して、すべてのINMEMORYオブジェクトの移入タスクを送信します。優先度がNONEの場合、このファンクションはすべてのINMEMORYオブジェクトの移入を開始します。POPULATE_WAITは、優先度設定のない外部表には適用しません。
関数は移入パーセンテージを入力(デフォルトは100)およびタイムアウト間隔(デフォルトは99999999秒(115.74日))としてを受け入れます。関数を実行すると、データベースは指定されたPRIORITY基準を満たすオブジェクトの移入をタイムアウト間隔内で試行し、次に移入ステータスを示す値を返します。
次の表に、POPULATE_WAITで想定される戻り値を示します。この関数は、timeoutで指定された間隔の終了前に条件が満たされた場合にのみ、値0、1、2および3を返します。たとえば、timeoutが600の場合に、600秒経過する前にメモリー不足エラーが発生した場合にのみ、この関数は1を返します。このファンクションは、データベースがリクエストされた操作を完了する前に、タイムアウト間隔が終了になった場合にのみ-1を返します。
表6-1 POPULATE_WAITの戻り値
| 定数 | 値 | 説明 |
|---|---|---|
|
|
|
移入の完了を待機中に関数がタイムアウトしました。 現在の移入ジョブは、 |
|
|
|
|
|
|
|
インメモリー・プールに、指定した完了の |
|
|
|
指定した |
|
|
|
インメモリー列ストアが有効になっていません。 |
関連項目:
-
DBMS_INMEMORY_ADMINパッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
DBMS_INMEMORY.REPOPULATEを使用した移入
DBMS_INMEMORY.REPOPULATEは、現在IM列ストアに移入されている表、パーティションまたはサブパーティションを強制的に再移入します。
このプロシージャを現在移入されていないインメモリー・オブジェクトに使用する場合、このプロシージャはDBMS_INMEMORY.POPULATEと機能的に同等です。
関連項目:
-
DBMS_INMEMORYパッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
FULLヒントについてさらに学習するには、『Oracle Database SQL言語リファレンス』を参照
インメモリー・オブジェクトの初期移入の強制
全表スキャン、POPULATEプロシージャ、POPULATE_WAIT関数またはREPOPULATEプロシージャを使用して、オブジェクトの移入を強制できます。
前提
このタスクでは、次のことを想定しています。
-
IM列ストアが有効になっている。
-
表をインメモリー移入できるようにする。
-
IM列ストアへの表の即時移入を強制的に実行する必要がある。
ノート:
テキスト列ベースの問合せは、IMEU (インメモリー式単位)の移入が終了した後にのみ実行する必要があります。IMEUの移入が進行中に実行される問合せの実行は、通常よりもはるかに遅くなります。INMEMORY表の移入を強制的に実行するには:
-
SQL*PlusまたはSQL Developerで、管理者権限を持つユーザーとしてデータベースにログインします。
-
INMEMORY属性を表に適用します。たとえば、次のように
sh.customersをIM移入のために有効にします。ALTER TABLE sh.customers INMEMORY;前述の例では、デフォルトの優先度は
NONEです。 -
必要な場合は、
V$IM_SEGMENTSを問い合せて移入ステータスを確認します。たとえば、次の文を使用します(出力例が含まれています)。
COL OWNER FORMAT a10; COL NAME FORMAT a25; COL STATUS FORMAT a10; SELECT OWNER, SEGMENT_NAME NAME, POPULATE_STATUS STATUS FROM V$IM_SEGMENTS WHERE SEGMENT_NAME = 'CUSTOMERS'; no rows selected上の出力では、オブジェクトがまだIM列ストアに移入されていないことが示されています。
-
次のいずれかの方法で移入を開始します。
-
FULLヒントを指定したSELECTを使用して、表のすべての行を問い合せます。たとえば、次の文を発行します。
SELECT /*+ FULL(customers) NO_PARALLEL(customers) */ COUNT(*) FROM sh.customers; -
DBMS_INMEMORY.POPULATEプロシージャを実行します。たとえば、このプロシージャを次のように、
sh.customersに対して実行します。EXEC DBMS_INMEMORY.POPULATE('SH', 'CUSTOMERS'); -
DBMS_INMEMORY.REPOPULATEプロシージャを実行します。移入されていない表の場合、このプロシージャは
POPULATEと機能的に同じです。たとえば、このプロシージャを次のように、sh.customersに対して実行します。EXEC DBMS_INMEMORY.REPOPULATE('SH', 'CUSTOMERS'); -
DBMS_INMEMORY_ADMIN.POPULATE_WAIT関数を実行します。次のコード例では、
PRIORITY設定に関係なく、すべてのINMEMORYオブジェクトを移入します。例では、すべてのオブジェクトが100%移入されるまで関数が待機するように指定します。また、1800秒(30分)以内に正常終了しなかった場合はエラーでタイムアウトする必要があります。VARIABLE b_pop_status NUMBER BEGIN SELECT DBMS_INMEMORY_ADMIN.POPULATE_WAIT( priority => 'NONE' , percentage => 100 , timeout => 1800 , force => FALSE ) INTO :b_pop_status FROM dual; END; / PRINT b_pop_status
-
-
必要な場合は、移入ステータスを確認するために、
V$IM_SEGMENTSを問い合せます。たとえば、次の文を使用します(出力例が含まれています)。
SELECT OWNER, SEGMENT_NAME NAME, POPULATE_STATUS STATUS FROM V$IM_SEGMENTS WHERE SEGMENT_NAME = 'CUSTOMERS'; OWN NAME STATUS --- ---------- -------------------- SH CUSTOMERS COMPLETEDこれで、表がIM列ストアに移入されました。
関連項目:
-
V$IM_SEGMENTSについて学習するには、『Oracle Databaseリファレンス』を参照 -
DBMS_INMEMORYサブプログラムについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
インメモリー表の手動での移入: 例
次の例は、インメモリー表を手動で移入する方法を示しています。
関連項目:
全表スキャンを使用したインメモリー表の移入: 例
この例では、全表スキャンを使用してsh.sales表をIM列ストアに移入します。
管理者としてデータベースにログインし、次のDDL文を発行してsh.sales表にINMEMORY句を追加したと仮定します。
ALTER TABLE sh.sales INMEMORY;
上の文では、INMEMORY句のデフォルトであるMEMCOMPRESS FOR QUERYおよびPRIORITY NONEが使用されます。PRIORITYがNONEであるため、データベースは表をIM列ストアに自動的に移入しません。次の問合せは、sh.sales表が現在移入されていないことを確認します。
COL OWNER FORMAT a10;
COL NAME FORMAT a25;
COL STATUS FORMAT a10;
SELECT OWNER, SEGMENT_NAME NAME,
POPULATE_STATUS STATUS
FROM V$IM_SEGMENTS
WHERE SEGMENT_NAME = 'SALES';
no rows selected次の問合せはFULLヒントを使用してsalesの全表スキャンを強制し、それによって移入を開始します(出力例を含む)。
SELECT /*+ FULL(sales) NO_PARALLEL(sales) */ COUNT(*) FROM sh.sales;
COUNT(*)
----------
918843
次の問合せでは、salesの移入ステータスが示されます(出力例が含まれています)。
SET PAGESIZE 50000
COL OWNER FORMAT a3
COL NAME FORMAT a10
COL STATUS FORMAT a20
SELECT OWNER, SEGMENT_NAME NAME,
POPULATE_STATUS STATUS
FROM V$IM_SEGMENTS
WHERE SEGMENT_NAME = 'SALES';
OWN NAME STATUS
--- ---------- --------------------
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
SH SALES COMPLETED
16 rows selected.
次の問合せは表の圧縮率を計算します。この問合せは、表がディスク上でさらに圧縮されていないことが前提となります。
COL OWNER FORMAT a5
COL SEGMENT_NAME FORMAT a5
SET PAGESIZE 50000
SELECT v.OWNER, v.SEGMENT_NAME, v.BYTES ORIG_SIZE,
v.INMEMORY_SIZE IN_MEM_SIZE,
ROUND(v.BYTES / v.INMEMORY_SIZE, 2) COMP_RATIO
FROM V$IM_SEGMENTS v
ORDER BY 4;
OWNER SEGME ORIG_SIZE IN_MEM_SIZE COMP_RATIO
----- ----- ---------- ----------- ----------
SH SALES 851968 1310720 .65
SH SALES 835584 1310720 .64
SH SALES 925696 1310720 .71
SH SALES 958464 1310720 .73
SH SALES 950272 1310720 .73
SH SALES 786432 1310720 .6
SH SALES 876544 1310720 .67
SH SALES 753664 1310720 .58
SH SALES 1081344 1310720 .83
SH SALES 901120 1310720 .69
SH SALES 925696 1310720 .71
SH SALES 933888 1310720 .71
SH SALES 843776 1310720 .64
SH SALES 999424 1310720 .76
SH SALES 581632 1507328 .39
SH SALES 696320 1507328 .46
16 rows selected.OPULATEプロシージャを使用した表の移入: 例
この例ではDBMS_INMEMORY.POPULATEを使用して、sh.customers表のIM列ストアへの移入を開始します。
管理者としてデータベースにログインし、次のDDL文を発行してsh.customers表にINMEMORY句を追加したと仮定します。
ALTER TABLE sh.customers INMEMORY;
上の文では、INMEMORY句のデフォルトであるMEMCOMPRESS FOR QUERYおよびPRIORITY NONEが使用されます。PRIORITYがNONEであるため、データベースは表をIM列ストアに自動的に移入しません。次の問合せは、sh.customers表が現在移入されていないことを確認します。
COL OWNER FORMAT a10;
COL NAME FORMAT a25;
COL STATUS FORMAT a10;
SELECT OWNER, SEGMENT_NAME NAME,
POPULATE_STATUS STATUS
FROM V$IM_SEGMENTS
WHERE SEGMENT_NAME = 'CUSTOMERS';
no rows selected次のPL/SQLコードはイニシアティブの移入にPOPULATEプロシージャを使用します。
EXEC DBMS_INMEMORY.POPULATE('SH', 'CUSTOMERS');次の問合せでは、customersの移入ステータスが示されます(出力例が含まれています)。
SELECT OWNER, SEGMENT_NAME NAME,
POPULATE_STATUS STATUS
FROM V$IM_SEGMENTS
WHERE SEGMENT_NAME = 'CUSTOMERS';
OWN NAME STATUS
--- ---------- --------------------
SH CUSTOMERS COMPLETED
POPULATE_WAIT関数を使用したタイムアウトの設定: 例
この例では、優先度設定に関係なく、DBMS_INMEMORY_ADMIN.POPULATE_WAITを使用してすべてのインメモリー表を移入します。
例6-2 インメモリー移入のタイムアウト間隔の指定
この例では、データベースに様々な優先順位設定のあるインメモリー表が数多く含まれています。目標は、制限付きデータベース・セッションですべてのインメモリー表に100%の完了を移入し、制限付きセッションを無効にして、アプリケーションがインメモリー表現のみの問合せを行うことを保証できるようにすることです。
データベースは停止されていると仮定します。SQL*Plusでアイドル・インスタンスにSYSDBAとして接続し、次のコマンドを実行します(出力例を含む)。
SQL> STARTUP RESTRICT
ORACLE instance started.
Total System Global Area 1157624280 bytes
Fixed Size 8839640 bytes
Variable Size 754974720 bytes
Database Buffers 16777216 bytes
Redo Buffers 7933952 bytes
In-Memory Area 369098752 bytes
Database mounted.
Database opened.
データベースが開きますが、アクセスできるのは管理ユーザーのみです。SQL*Plusで次の文を実行します(出力例は太字で表示)。
VARIABLE b_pop_status NUMBER
SELECT DBMS_INMEMORY_ADMIN.POPULATE_WAIT(
priority => 'NONE' ,
percentage => 100 ,
timeout => 300 )
INTO b_pop_status
FROM DUAL;
PRINT b_pop_status
-1
5分後、関数が–1を返します。このコードは、移入か完了するのを待機している間に関数がタイムアウトしたことを示します。5分は、すべてのINMEMORY表を移入するのに十分な長さではありません。タイムアウトを30分に指定して、SELECT文を再実行します。
SELECT DBMS_INMEMORY_ADMIN.POPULATE_WAIT(
priority => 'NONE' ,
percentage => 100 ,
timeout => 1800 )
INTO b_pop_status
FROM DUAL;
PRINT b_pop_status
0
8分後、この関数は数値0を返します。このコードは、すべての表が完全に移入されていることを示します。制限付きセッションを無効にします。これによりアプリケーションは、インメモリー表現のみにアクセスするという完全な信頼度でインメモリー・オブジェクトの問合せを開始できます。
ALTER SYSTEM DISABLE RESTRICTED SESSION;
DBMS_INMEMORY.POPULATEを使用したインメモリー外部表への移入: 例
この例では、INMEMORYオプションを持つ外部表を移入します。
この例では、sh_sales.csvファイルを使用して、INMEMORYオプションを指定した外部表sh.admin_ext_salesを作成していると仮定します。
admin_ext_sales表はまだ移入されていません。Oracle Database19c以降、全表スキャンでは標準表への移入と同様に外部表が移入されます。ただし、このシナリオでは、DBMS_INMEMORYパッケージを使用して移入の開始を選択します。
ノート:
インメモリーの外部表を問い合せるセッションでは、初期化パラメータQUERY_REWRITE_INTEGRITYをstale_toleratedに設定する必要があります。
外部表が変更された場合、IM列ストアからの結果は未定義であることに注意してください。パーティションが(値を削除または追加して)変更された場合も、結果は未定義です。これにより、IMベースとIM以外のスキャンの結果に違いが生じる可能性があります。DBMS_INMEMORY.REPOPULATEを実行してIMストアをリフレッシュし、表データと再同期化できます。
表に移入するには、次のステップを実行します。
-
ユーザー
shとしてログインします。 -
データベース・セッションで
QUERY_REWRITE_INTEGRITYを設定します。ALTER SESSION SET QUERY_REWRITE_INTEGRITY=stale_tolerated; -
次のPL/SQLプログラムを実行します。
EXEC DBMS_INMEMORY.POPULATE('SH', 'ADMIN_EXT_SALES'); -
V$IM_SEGMENTSを問い合せて、移入ステータスを確認します。COL OWNER FORMAT a3 COL NAME FORMAT a15 COL STATUS FORMAT a9 SELECT OWNER, SEGMENT_NAME NAME, POPULATE_STATUS STATUS FROM V$IM_SEGMENTS; OWN NAME STATUS --- --------------- --------- SH ADMIN_EXT_SALES COMPLETED前述の出力は、
admin_ext_sales表が移入されたことを示しています
関連項目:
-
DBMS_INMEMORY.POPULATEについてさらに学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
QUERY_REWRITE_INTEGRITY初期化パラメータについて学習するには、『Oracle Databaseリファレンス』を参照
REPOPULATEプロシージャを使用したインメモリー外部表のリフレッシュ: 例
この例では、現在移入されているインメモリー外部表を再移入します。
/tmp/data/sh_sales.csvを使用して、INMEMORYオプションを指定してsh.admin_ext_sales表を作成し、この表をIM列ストアに移入したと仮定します。
次のように、レコードを/tmp/data/sh_sales.csvに追加したとします。
echo "148,8787,23-NOV-01,2,999,1,23.43" >> /tmp/data/sh_sales.csv-
DBMS_INMEMORY.REPOPULATEプロシージャをコールします -
表を
NO INMEMORYとして指定し、それをINMEMORYとして指定して、全表スキャンを実行します
次の例ではREPOPULATEプロシージャを使用して、IM列ストアにadmin_ext_salesを強制的にリフレッシュさせます。
EXEC DBMS_INMEMORY.REPOPULATE('SH', 'ADMIN_EXT_SALES');関連項目:
-
DBMS_INMEMORY.REPOPULATEについてさらに学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。