[Database] New in 18c: Introduction to In-Memory External Tables in 18c

原文はこちら。
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ストレージに再度複製する必要がないデータ
エンタープライズデータとビッグデータを単に統合するだけでは、企業にとって価値は生まれないため、両方のソースからのデータを利用して高度な分析をする必要があります。このようなクエリでは、データアナリストが収益向上のために複数の手段を検討するため、繰り返しアプローチが必要になることがよくあります。これらの分析は、あらゆるエコシステムで最も豊富なSQLツールが存在するOracle Database内で実行する必要があり、両方のデータ・ソースへの高性能なアクセスが必要です。比較的短い時間内に外部データを繰り返しクエリする必要がある場合は、HDFSや他の外部ディスク・フォーマットにアクセスすることはコスト効率が悪いため、OracleのDBIM技術の恩恵を受けることができます。

18.1より前では、外部データをOracle Databaseにロードせずに高速スキャンを実行する方法はありませんでした。以前のリリースで使用された、繰り返しの負荷や高性能スキャンを実行するために利用されたメカニズムの1つは、以下のようなものでした。
Create Materialized View <imxtmv>
Build Immediate Refresh Complete On Demand As
Select * From <external table> INMEMORY;
INMEMORY Materialized Viewを作成し、Query_Rewrite_Integrity parameterセッションをSTALE_TOLERATEDに設定します。この場合、クエリプランはその行ソースとしてMAT_VIEW ACCESS INMEMORY FULLと表示されます。

その他関連するリクエストとして、以下のようなものがありました。
  • 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句と同じセクションの表定義の最後にあります。
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;
全てのDBIM圧縮レベルがサポートされ、ヒープ表で実施している場合と同じ意味です。
  • 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
'INMEMORY'を単独で使用すると、 'INMEMORY MEMCOMPRESS FOR QUERY LOW'が表示されます。

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であることを明示的に知らせる必要があります。 これは次のように設定します。
SQL> alter session set query_rewrite_integrity=stale_tolerated;
最初に記載したユースケースについては、実のところリアルなメリットがあります。例えば、外部プロセスがcsv形式で出力を生成したり、またはmap-reduceジョブがHDFSファイルを作成したりしているとします。インメモリスナップショットをディスクファイルから切り離すと、実行中のクエリを中断することなく外部プロセスを完了できます。次に、外部プロセスが完了したら、dbms_inmemory.repopulateを呼び出して外部データの新しいIn-Memoryスナップショットを作成することができます。 現在、古いスナップショットに対して実行されているクエリは、IMCU(In-Memory Compression Unit、インメモリ圧縮ユニット)の読み取りラッチを保持するため、正常に完了するはずです。

Data Dictionary

外部表の In-Memory 属性を以下の6個のビューのいずれかで確認できます。
  1. USER_EXTERNAL_TABLES
  2. ALL_EXTERNAL_TABLES
  3. DBA_EXTERNAL_TABLES
  4. USER_TABLES
  5. ALL_TABLES
  6. 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
3 rows selected.
また、DBIMが外部表を含めるために利用するv$ビューの一部を拡張しています。

v$im_segments とv$im_segment_detail というビューは両者ともIS_EXTERNALという新しい列を持ち、値としてTRUE、FALSEを取ります。例えば、サンプル表をリードし、ヒープ表にサンプル表からデータをロードします。
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     
In-Memory外部表をクエリする前に、表が完全にロードされていることを確認するため、v$im_segmentsのbytes_not_populatedおよびpopulate_status列をチェックする必要があります。

Notes

  • 現在サポートされている外部表ドライバは、ORACLE_LOADERおよびORACLE_DATAPUMPです。
  • 外部表のインメモリコンテンツを更新するために、DBMS_INMEMORY.(re)populateを明示的に起動する必要があります。
  • 外部表のインメモリコンテンツの移入はシリアル(直列)です。
  • In-Memory外部表のシリアルスキャンのみがサポートされています。 Parallel Queryはまだサポートされていません。
    • インメモリースキャンが外部表に対するスキャンよりもはるかに高速であるため、重大なパフォーマンスの障害になることはまずありません。
  • INMEMORY句のMEMCOMPRESS副句だけがサポートされています。PRIORITY、DISTRIBUTEおよびDUPLICATEの副句はまだサポートされていません。
  • パーティション化されていない外部表のみがサポートされています。パーティションまたはパーティション化された外部表の最上位レベルでINMEMORYを指定すると、エラーが発生します。

0 件のコメント:

コメントを投稿