5 IM列ストアの手動での移入
データベースはPRIORITY
設定がNONE
のインメモリー・オブジェクトを自動的に移入しません。これらのオブジェクトに移入するには、SQLまたはPL/SQLを実行する必要があります。
この章のトピックは、次のとおりです:
5.1 インメモリー・オブジェクトの手動移入について
全表スキャン、DBMS_INMEMORY
プログラム・ユニット、またはDBMS_INMEMORY_ADMIN.POPULATE_WAIT
のいずれかを使用して、手動でオブジェクトを移入します。
PRIORITY
をNONE
に設定してオブジェクトを有効にし、そのオブジェクトをすぐに追加する場合は、次のセクションで説明するオプションを使用できます。
5.1.1 SELECTを使用した移入
表スキャンを強制するSELECT
文を発行して、移入を開始できます。
この場合、データベースはオブジェクトの各行を読み取り、それを列形式に変換します。次の文は全表スキャンを保証しません。
SELECT COUNT(*) FROM object
これは、オプティマイザが索引のスキャンを選択するためです。したがって、次の例に示すように、SELECT COUNT(*)
問合せの FULL
ヒントを使用して全表スキャンを強制することをお薦めします。
SELECT /*+ FULL(customers) NO_PARALLEL(customers) */ COUNT(*) FROM customers;
関連項目:
-
FULL
ヒントについてさらに学習するには、『Oracle Database SQL言語リファレンス』を参照
5.1.2 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パッケージおよびタイプ・リファレンス』を参照
5.1.3 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
を返します。
表5-1 POPULATE_WAITの戻り値
定数 | 値 | 説明 |
---|---|---|
|
|
移入の完了を待機中に関数がタイムアウトしました。 現在の移入ジョブは、 |
|
|
|
|
|
インメモリー・プールに、指定した完了の |
|
|
指定した |
|
|
インメモリー列ストアが有効になっていません。 |
関連項目:
-
DBMS_INMEMORY_ADMIN
パッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
5.1.4 DBMS_INMEMORY.REPOPULATEを使用した移入
DBMS_INMEMORY.REPOPULATE
は、現在IM列ストアに移入されている表、パーティションまたはサブパーティションを強制的に再移入します。
このプロシージャを現在移入されていないインメモリー・オブジェクトに使用する場合、このプロシージャはDBMS_INMEMORY.POPULATE
と機能的に同等です。
関連項目:
-
DBMS_INMEMORY
パッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
FULL
ヒントについてさらに学習するには、『Oracle Database SQL言語リファレンス』を参照
5.2 インメモリー・オブジェクトの初期移入の強制
全表スキャン、POPULATE
プロシージャ、POPULATE_WAIT
関数またはREPOPULATE
プロシージャを使用して、オブジェクトの移入を強制できます。
前提
このタスクでは、次のことを想定しています。
-
IM列ストアが有効になっている。
-
表をインメモリー移入できるようにする。
-
IM列ストアへの表の即時移入を強制的に実行する必要がある。
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パッケージおよびタイプ・リファレンス』を参照
5.3 インメモリー表の手動での移入: 例
次の例は、インメモリー表を手動で移入する方法を示しています。
関連項目:
5.3.1 全表スキャンを使用したインメモリー表の移入: 例
この例では、全表スキャンを使用して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.
5.3.2 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
5.3.3 POPULATE_WAIT関数を使用したタイムアウトの設定: 例
この例では、優先度設定に関係なく、DBMS_INMEMORY_ADMIN.POPULATE_WAIT
を使用してすべてのインメモリー表を移入します。
例5-1 インメモリー移入のタイムアウト間隔の指定
この例では、データベースに様々な優先順位設定のあるインメモリー表が数多く含まれています。目標は、制限付きデータベース・セッションですべてのインメモリー表に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;
5.3.4 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リファレンス』を参照
5.3.5 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パッケージおよびタイプ・リファレンス』を参照してください。