原文はこちら。
https://blogs.oracle.com/in-memory/introduction-to-in-memory-external-tables-in-18c
2014年6月14日、Larry Ellisonは公式に同じデータを行方向、列方向のいずれからでも透過的にアクセスするための革命的なデュアルフォーマットストレージを導入した、新しいOracle Database In-Memoryオプションのローンチを発表しました。その年のOracle OpenWorldでは、ISV2社がIn-Memory External Tables(IMXT、インメモリ外部表)のサポートのリクエストをしてきました。IMXTのユースケースは以下のようなものです。
18.1より前では、外部データをOracle Databaseにロードせずに高速スキャンを実行する方法はありませんでした。以前のリリースで使用された、繰り返しの負荷や高性能スキャンを実行するために利用されたメカニズムの1つは、以下のようなものでした。
その他関連するリクエストとして、以下のようなものがありました。
INMEMORY句は、Reject Limit句と同じセクションの表定義の最後にあります。
したがって、In-Memoryスキャンは外部スキャンとは異なる結果を返す可能性があるため、リフレッシュ・オンデマンド・マテリアライズド・ビューを使用する場合と同じように、ユーザーはこれでOKであることを明示的に知らせる必要があります。 これは次のように設定します。
v$im_segments とv$im_segment_detail というビューは両者ともIS_EXTERNALという新しい列を持ち、値としてTRUE、FALSEを取ります。例えば、サンプル表をリードし、ヒープ表にサンプル表からデータをロードします。
https://blogs.oracle.com/in-memory/introduction-to-in-memory-external-tables-in-18c
2014年6月14日、Larry Ellisonは公式に同じデータを行方向、列方向のいずれからでも透過的にアクセスするための革命的なデュアルフォーマットストレージを導入した、新しいOracle Database In-Memoryオプションのローンチを発表しました。その年のOracle OpenWorldでは、ISV2社がIn-Memory External Tables(IMXT、インメモリ外部表)のサポートのリクエストをしてきました。IMXTのユースケースは以下のようなものです。
- 顧客がOracleストレージにロードしたくないけれども、短時間で繰り返しスキャンする必要がある、価値の低いデータまたは一時的なデータ
- Map/Reduceやその他のHadoopアグリゲーションツールで集約されたビッグデータ(レポート用にエンタープライズデータと結合する必要があります)
- RDBMS側とHadoopツールの両方から問合せを行う必要があるため、Oracleストレージに再度複製する必要がないデータ
18.1より前では、外部データをOracle Databaseにロードせずに高速スキャンを実行する方法はありませんでした。以前のリリースで使用された、繰り返しの負荷や高性能スキャンを実行するために利用されたメカニズムの1つは、以下のようなものでした。
INMEMORY Materialized Viewを作成し、Query_Rewrite_Integrity parameterセッションをSTALE_TOLERATEDに設定します。この場合、クエリプランはその行ソースとしてMAT_VIEW ACCESS INMEMORY FULLと表示されます。Create Materialized View <imxtmv>
Build Immediate Refresh Complete On Demand As
Select * From <external table> INMEMORY;
その他関連するリクエストとして、以下のようなものがありました。
- In-Memory DBLINKs
- In-Memory only Materialized Views
What's in Oracle 18.1
18.1では、2個のレガシー・ドライバ(ORACLE_LOADERおよびORACLE_DATAPUMP)を使用する外部表用のINMEMORY MEMCOMPRESS句を実装しました。ビッグ・データ・ドライバ(ORACLE_HDFSおよびORACLE_HIVE)のサポートを追加しています。INMEMORY句は、Reject Limit句と同じセクションの表定義の最後にあります。
全てのDBIM圧縮レベルがサポートされ、ヒープ表で実施している場合と同じ意味です。create table s_et(
s_suppkey number ,
s_name char(25) ,
s_address varchar2(40) ,
s_nationkey number ,
s_phone char(15) ,
s_acctbal number ,
s_comment varchar2(101)
)
organization external (
type ORACLE_LOADER
default directory T_WORK
access parameters
(
records delimited by newline
nobadfile
nologfile
fields terminated by '|'
missing field values are null
)
location (T_WORK:'supplier.tbl'))
reject limit unlimited
INMEMORY MEMCOMPRESS FOR CAPACITY;
- NO INMEMORY
- INMEMORY
- INMEMORY NO MEMCOMPRESS
- INMEMORY MEMCOMPRESS FOR QUERY LOW
- INMEMORY MEMCOMPRESS FOR QUERY HIGH
- INMEMORY MEMCOMPRESS FOR CAPACITY LOW
- INMEMORY MEMCOMPRESS FOR CAPACITY HIGH
Table must be fully loaded before use
ヒープ表との主な違いの1つは、テーブル・スキャンで使用できるようになる前に、インメモリ外部表が完全にメモリにロードされている必要があります。外部表では現在、ハイブリッドIn-Memory/On-Diskスキャンはサポートされていません。v$im_segmentsを使用して母集団の状態を確認する方法については、以下のData Dictionaryの章をご覧ください。Session must set Query_Rewrite_Integrity
In-Memory外部表は、リフレッシュ・オンデマンド・マテリアライズド・ビューのように機能します。In-Memory領域にデータが移入されると、Location句で指定された外部ファイルの変更を認識しません。ヒープ表とは異なり、外部表は一般的にDMLをサポートしていないため、問題はほとんどの場合、1個以上の異なる(より新しい)バージョンに置き換えられている可能性がある、という点です。したがって、In-Memoryスキャンは外部スキャンとは異なる結果を返す可能性があるため、リフレッシュ・オンデマンド・マテリアライズド・ビューを使用する場合と同じように、ユーザーはこれでOKであることを明示的に知らせる必要があります。 これは次のように設定します。
最初に記載したユースケースについては、実のところリアルなメリットがあります。例えば、外部プロセスがcsv形式で出力を生成したり、またはmap-reduceジョブがHDFSファイルを作成したりしているとします。インメモリスナップショットをディスクファイルから切り離すと、実行中のクエリを中断することなく外部プロセスを完了できます。次に、外部プロセスが完了したら、dbms_inmemory.repopulateを呼び出して外部データの新しいIn-Memoryスナップショットを作成することができます。 現在、古いスナップショットに対して実行されているクエリは、IMCU(In-Memory Compression Unit、インメモリ圧縮ユニット)の読み取りラッチを保持するため、正常に完了するはずです。SQL> alter session set query_rewrite_integrity=stale_tolerated;
Data Dictionary
外部表の In-Memory 属性を以下の6個のビューのいずれかで確認できます。- USER_EXTERNAL_TABLES
- ALL_EXTERNAL_TABLES
- DBA_EXTERNAL_TABLES
- USER_TABLES
- ALL_TABLES
- DBA_TABLES
SQL> column TABLE_NAME format a10
SQL> select table_name, inmemory, inmemory_compression
2 from user_tables where EXTERNAL = 'YES'
TABLE_NAME INMEMORY INMEMORY_COMPRESS
---------- -------- -----------------
R_ET DISABLED
N_ET DISABLED
S_ET ENABLED FOR QUERY LOW
また、DBIMが外部表を含めるために利用するv$ビューの一部を拡張しています。3 rows selected.
v$im_segments とv$im_segment_detail というビューは両者ともIS_EXTERNALという新しい列を持ち、値としてTRUE、FALSEを取ります。例えば、サンプル表をリードし、ヒープ表にサンプル表からデータをロードします。
In-Memory外部表をクエリする前に、表が完全にロードされていることを確認するため、v$im_segmentsのbytes_not_populatedおよびpopulate_status列をチェックする必要があります。SQL> exec dbms_inmemory.populate(USER,'S_ET');
PL/SQL procedure successfully completed.
SQL> exec dbms_inmemory.populate(USER,'SUPPLIER');
PL/SQL procedure successfully completed.
SQL> select SEGMENT_NAME,INMEMORY_SIZE,BYTES_NOT_POPULATED,POPULATE_STATUS,IS_EXTERNAL
from v$im_segments;
SEGMENT_NAME INMEMORY_SIZE BYTES_NOT_POPULATED POPULATE_STAT IS_EX
------------ ------------- ------------------- ------------- -----
SUPPLIER 2359296 0 COMPLETED FALSE
S_ET 2228224 0 COMPLETED TRUE
Notes
- 現在サポートされている外部表ドライバは、ORACLE_LOADERおよびORACLE_DATAPUMPです。
- 外部表のインメモリコンテンツを更新するために、DBMS_INMEMORY.(re)populateを明示的に起動する必要があります。
- 外部表のインメモリコンテンツの移入はシリアル(直列)です。
- In-Memory外部表のシリアルスキャンのみがサポートされています。 Parallel Queryはまだサポートされていません。
- インメモリースキャンが外部表に対するスキャンよりもはるかに高速であるため、重大なパフォーマンスの障害になることはまずありません。
- INMEMORY句のMEMCOMPRESS副句だけがサポートされています。PRIORITY、DISTRIBUTEおよびDUPLICATEの副句はまだサポートされていません。
- パーティション化されていない外部表のみがサポートされています。パーティションまたはパーティション化された外部表の最上位レベルでINMEMORYを指定すると、エラーが発生します。