2 インメモリー列ストアのアーキテクチャ
インメモリー列ストア(IM列ストア)では、高速スキャン用に最適化された列形式を使用して、表およびパーティションがメモリーに格納されます。Oracle Databaseでは、高機能なアーキテクチャを使用して、列形式と行形式で同時にデータを管理します。
この章のトピックは、次のとおりです:
2.1 デュアルフォーマット: 列と行
IM列ストアを有効にした場合は、SGAにより、インメモリー領域とデータベース・バッファ・キャッシュという別々の場所でデータが管理されます。
IM列ストアでは、データが列形式でエンコードされます。各列は独立した構造となります。それらの列は隣接して格納され、分析問合せのために最適化されます。データベース・バッファ・キャッシュでは、IM列ストアにも移入されるオブジェクトを変更できます。ただし、バッファ・キャッシュでは、データが従来の行形式で格納されます。データ・ブロックでは、行はトランザクションのために最適化され、隣接して格納されます。
次の図では、行ベースのストレージと列ストレージとの違いを示します。
この項の内容は次のとおりです。
2.1.1 インメモリー領域内の列データ
インメモリー領域は、IM列ストアが含まれる、オプションのSGAコンポーネントです。
この項では、次の項目について説明します。
2.1.1.1 インメモリー領域のサイズ
インメモリー領域は、INMEMORY_SIZE
初期化パラメータによって制御されます。デフォルトでは、インメモリー領域のサイズは0であり、これは、IM列ストアが無効になっていることを意味します。
IM列ストアを有効にするには、インメモリー領域を少なくとも100 MBに設定します。サイズは、V$SGA
で示されます。
インメモリー領域は、SGA_TARGET
初期化パラメータの設定から差し引かれます。たとえば、SGA_TARGET
を10 GBに設定し、INMEMORY_SIZE
を4 GBに設定した場合は、SGA_TARGET
設定の40%がインメモリー領域に割り当てられます。次の図に、この関係を示します。
バッファ・キャッシュおよび共有プールなど、SGAのその他のコンポーネントと異なり、インメモリー領域のサイズは、自動メモリー管理によって制御されません。データベースでは、バッファ・キャッシュまたは共有プールでさらにメモリーが必要な場合に自動的にインメモリー領域が縮小されることや、インメモリー領域が領域不足の場合に拡大されることはありません。
Oracle Database 12cリリース2 (12.2)以降は、ALTER SYSTEM
文を使用することで、INMEMORY_SIZE
を動的に拡大できます。次の条件が満たされた場合に、データベースにより、増加したメモリーが割り当てられます。
-
SGAに空きメモリーがある。
-
INMEMORY_SIZE
の新しいサイズが、現在の設定よりも128 MB以上大きい。ノート:
ALTER SYSTEM
を使用してINMEMORY_SIZE
を縮小することはできません。
V$INMEMORY_AREA
およびV$SGA
ビューには、即座にその変更内容が反映されます。
関連項目:
-
自動メモリー管理についてさらに学習するには、『Oracle Database管理者ガイド』を参照
-
INMEMORY_SIZE
、V$INMEMORY_AREA
およびV$SGA
について学習するには、『Oracle Databaseリファレンス』を参照
2.1.1.2 インメモリー領域内のメモリー・プール
インメモリー領域は、列データおよびメタデータのために複数のサブプールに分割されます。
インメモリー領域は、さらに次のサブプールに分割されます。
-
このサブプールには、列データを含むIMCUが格納されます。例2-1で示すように、
V$INMEMORY_AREA.POOL
列では、このサブプールは1MB POOL
として識別されます。 -
このサブプールには、IM列ストア内に存在するオブジェクトについてのメタデータが格納されます。例2-1で示すように、
V$INMEMORY_AREA.POOL
列では、このサブプールは64KB POOL
として識別されます。
データベースでは、2つのサブプールの相対的なサイズは内部ヒューリスティックを使用して決まります。データベースでは、インメモリー領域内のほとんどの領域が列データ・プール(1 MBプール)に割り当てられます。
ノート:
Oracle Databaseにより、サブプール・サイズが自動的に決定されます。領域割当てを変更することはできません。
例2-1 V$INMEMORY_AREAビュー
この例では、V$INMEMORY_AREA
ビューを問い合せ、各サブプール内のメモリーの空き容量を測定します(出力例が含まれています)。
COL POOL FORMAT a9
COL POPULATE_STATUS FORMAT a15
SSELECT POOL, TRUNC(ALLOC_BYTES/(1024*1024*1024),2) "ALLOC_GB",
TRUNC(USED_BYTES/(1024*1024*1024),2) "USED_GB",
POPULATE_STATUS
FROM V$INMEMORY_AREA;
POOL ALLOC_GB USED_GB POPULATE_STATUS
--------- ---------- ---------- ---------------
1MB POOL 7.99 0 DONE
64KB POOL 1.98 0 DONE
インメモリー領域の現在のサイズはV$SGA
で表示可能です。
SELECT NAME, VALUE/(1024*1024*1024) "SIZE_IN_GB"
FROM V$SGA
WHERE NAME LIKE '%Mem%';
NAME SIZE_IN_GB
-------------------- ----------
In-Memory Area 10
この例では、サブプールに割り当てられているメモリーは9.97 GBであるのに対して、インメモリー領域のサイズは10 GBです。データベースでは、内部管理構造のためにメモリーのごく一部が使用されます。
2.1.2 データベース・バッファ・キャッシュ内の行データ
データベース・バッファ・キャッシュでは、IM列ストアが有効でも無効でも同じようにデータ・ブロックが格納および処理されます。バッファI/Oおよびバッファ・プールは、同じ機能を果たします。
IM列ストアによって、データは従来の行形式(バッファ・キャッシュ)および列形式の両方でSGAに同時に移入されます。データベースは透過的にOLTP問合せ(主キー参照など)をバッファ・キャッシュに送信し、分析問合せおよびレポート問合せをIM列ストアに送信します。データをフェッチする場合は、Oracle Databaseで、同じ問合せ内で両方のメモリー領域からデータを読み取ることもできます。
ノート:
実行計画では、操作TABLE ACCESS IN MEMORY FULL
は、IM列ストア内で一部またはすべてのデータがアクセスされることを示します。
デュアル形式アーキテクチャではメモリー要件は倍増しません。バッファ・キャッシュは、データベースのサイズよりもはるかに小さいサイズで稼働するように最適化されます。
次の図に、IM列ストアのサンプルを示します。データベースで、sh.sales
表がディスクに従来の行形式で格納されます。SGAはデータをIM列ストアに列形式で格納し、データベース・バッファ・キャッシュに行形式で格納します。
永続的なヒープ構成表のどのディスク上データ形式もみな、IM列ストアでサポートされます。列形式は、データ・ファイルまたはバッファ・キャッシュに格納されているデータの形式には影響せず、データのUNDO、オンラインREDOロギングにも影響しません。
データベースでは、バッファ・キャッシュ、オンラインREDOログおよびUNDO表領域を更新することで、IM列ストアが有効になっているかどうかにかかわらず、DML変更が同じ方法で処理されます。ただし、データベースは内部メカニズムを使用して変更を追跡し、IM列ストアと残りのデータベースとの一貫性を保ちます。たとえば、sales
表がIM列ストアに移入されており、アプリケーションによってsales
内の行が更新される場合、データベースでは、自動的にIM列ストア内のsales
表のコピーに関してトランザクションの一貫性が保たれます。IM列ストアにアクセスする問合せは常に、バッファ・キャッシュにアクセスする問合せと同じ結果を返します。
関連項目:
データベース・バッファ・キャッシュについてさらに学習するには、Oracle Database概要を参照してください。
2.2 インメモリー記憶域単位
IM列ストアでは、データとメタデータの両方が、従来のOracleデータ・ブロックではなく、最適化された記憶域単位で管理されます。
Oracle Databaseでは、記憶域単位はインメモリー領域内で保持されます。次の図では、インメモリー領域の概要、およびそれとやり取りするデータベース・プロセスを示します。残りの章では、様々なメモリー・コンポーネントを説明します。
この項では、次の項目について説明します。
2.2.1 インメモリー圧縮ユニット(IMCU)
インメモリー圧縮単位(IMCU)は、圧縮された、読取り専用の記憶域単位であり、1つ以上の列のためにデータを含みます。
IMCUは、表領域エクステントに似ています。IMCUには、一連の列圧縮単位(CU)、およびIM記憶域索引などのメタデータを含むヘッダーという、2つの部分があります。
この項では、次の項目について説明します。
2.2.1.1 IMCUとスキーマ・オブジェクト
IM列ストアでは、一連のIMCUに、単一のオブジェクト(表、パーティション、マテリアライズド・ビュー)のデータが格納されます。IMCUには、1つのオブジェクトについてのみ列データが格納されます。
INMEMORY
として指定されたオブジェクトの場合は、INMEMORY
句でリストされたすべての列がすべてのIMCUに含まれます。たとえば、図2-6で示すように、sh.sales
表に7つの列があるとします。次のDDL文では、その表がINMEMORY
として指定されます。これは、sales
のためのすべてのIMCUに、これら7列の列データが含まれることを意味します。
ALTER TABLE sh.sales INMEMORY MEMCOMPRESS FOR QUERY LOW;
INMEMORY
属性をセグメント内の列のサブセットに適用するには、1つのDDL文ですべての列をINMEMORY
として指定してから、2つ目のDDL文を発行してNO INMEMORY
属性を除外列に対して指定します。たとえば、次の文では、sh.sales
内の3列がNO INMEMORY
であると指定されます。これは、その表内の他の4列がそれらのINMEMORY
属性を保持することを意味します。
ALTER TABLE sh.sales INMEMORY MEMCOMPRESS FOR QUERY LOW
NO INMEMORY (promo_id, quantity_sold, amount_sold);
次の図では、customers
、products
およびsales
という、IM列ストアに移入されたsh
スキーマからの3つの表を示します。この例では、各表で、異なる数の列にINMEMORY
が指定されています。各表のIMCUには、指定された列のデータのみが含まれています。
この項では、次の項目について説明します。
関連項目:
ALTER TABLE
文について学習するには、『Oracle Database SQL言語リファレンス』を参照してください。
2.2.1.1.1 インメモリー圧縮
IM列ストアでは、記憶域の削減よりはむしろアクセス速度の面で最適化された特別な圧縮形式が使用されます。列形式によって問合せを、圧縮された列に対して直接実行できます。
圧縮により、スキャン操作およびフィルタ操作で処理するデータ量を非常に少なくできるため、問合せパフォーマンスが向上します。Oracle Databaseでは結果セットに必要な場合のみ、データが圧縮解除されます。
IM列ストアで適用される圧縮は、ハイブリッド列圧縮と密接に関係しています。どちらの技術も列ベクターを処理します。主な違いは、IM列ストアの列ベクターがSIMDベクター処理の面で最適化されているのに対し、ハイブリッド列圧縮の列ベクターはディスク記憶域の面で最適化されている点です。
オブジェクトをIM列ストアに移入できるようにする場合は、INMEMORY
句で、FOR DML
、FOR QUERY
(LOW
またはHIGH
)、FOR CAPACITY
(LOW
またはHIGH
)またはNONE
の圧縮タイプを指定します。
関連項目:
-
ハイブリッド列圧縮についてさらに学習するには、『Oracle Database概要』を参照
2.2.1.1.2 IMCUと行
各IMCUには、表セグメント内の行のサブセットのすべての列値(nullを含む)が含まれます。行のサブセットは、グラニュルと呼ばれます。
指定されたセグメントのすべてのIMCUには、ほぼ同数の行が含まれます。Oracle Databaseでは、データ型、データ形式および圧縮タイプに応じて、グラニュルのサイズが自動的に判断されます。圧縮レベルが高いと、IMCU内の行数が多くなります。
IMCUとデータベース・ブロックのセットの間には1対多マッピングが存在します。例2-2で示すように、各IMCUには、異なるブロック・セットの列の値が格納されます。
IMCU内の列はソートされません。Oracle Databaseでは、それらはディスクから読み取られた順に移入されます。
IMCU内の行の数により、IMCUに使用される容量が決定されます。対象行数によって、1 MBプール内で使用可能な隣接する1 MBのエクステントの量を超えてIMCUが拡大する場合、IMCUにより、残りの列CUを保持するための追加のエクステント(ピース)が作成されます。IMCUでは、必ず1 MBずつ領域が割り当てられます。
例2-2 IMCUと行のサブセット
この単純化された例では、customers
表のcust_id
、cust_first_name
、cust_last_name
およびcust_gender
という4列のみにINMEMORY
属性があります。5行のみがその表に存在し、2つのデータ・ブロックに格納されています。概念的には、最初のデータ・ブロックにはその行が次のように格納されています。
82,Madeline,Li,F;37004,Abel,Embrey,M;1714,Hardy,Gentle,M
2つ目のデータ・ブロックには、行が次のように格納されています。
100439,Uma,Campbell,F;3047,Lucia,Downey,F
IMCU 1には最初のデータ・ブロックのデータが格納されると仮定します。このケースでは、このデータ・ブロック・ストア内のそれら3行のcust_id
列値は、CU内で次のように垂直に格納されます。
82
37004
1714
IMCU 2には、2つ目のデータ・ブロックからデータが格納されます。これら2行のcust_id
列値は、CU内で次のように格納されます。
100439
3047
cust_id
値はデータ・ブロック内の各行の最初の値であるため、cust_id
列は、IMCU内で先頭の位置にあります。列は必ず同じ位置を使用します。そのため、Oracle Databaseでは、セグメントのIMCUを読み取ることで、行を再構成できます。
関連トピック
2.2.1.2 列圧縮単位(CU)
列圧縮単位(CU)は、IMCU内の単一列のための隣接する記憶域です。すべてのIMCUに1つ以上のCUがあります。
この項では、次の項目について説明します。
2.2.1.2.1 CUの構造
CUは、本体とヘッダーに分けられます。
すべてのCUの本体には、IMCUに含まれている行の範囲で列値が格納されます。ヘッダーには、CU本体に格納されている値に関してメタデータが含まれます。たとえば、CU内の最小値および最大値です。また、ローカル・ディクショナリが含まれる場合もあります。これは、その列内の非重複値のソート済リスト、およびそれらに対応するディクショナリ・コードです。
次の図では、sales
表のprod_id
、cust_id
、time_id
およびchannel_id
という4つのCUがあるIMCUを示します。各CUには、IMCUに含まれている行の範囲で列値が格納されます。
CUには、ROWIDの順序で値が格納されます。このため、データベースは、行を元どおりにまとめることで問合せに答えることができます。たとえば、アプリケーションによって次のような問合せが発行されるとします。
SELECT cust_id, time_id, channel_id
FROM sales
WHERE prod_id =5;
データベースでは、まず、prod_id
列に値が5
のエントリがあるかどうかが調べられます。データベースで、prod_id
列内の位置2に5
が見つかったとします。データベースは、次に、この行の対応するcust_id
、time_id
およびchannel_id
を見つける必要があります。CUでは行順でデータが格納されるため、データベースは、対応するcust_id
、time_id
およびchannel_id
値をそれらの列内の位置2で見つけることができます。したがって、この問合せに答えるには、データベースは、cust_id
、time_id
およびchannel_id
列内の位置2から値を抽出し、行を元どおりにまとめ、それをエンド・ユーザーに返す必要があります。
2.2.1.2.2 ローカル・ディクショナリ
CUでは、ローカル・ディクショナリに、非重複値のリスト、およびそれらの対応するディクショナリ・コードが含まれます。
ローカル・ディクショナリには、列に含まれている記号が格納されます。次の図に、CUによるvehicles
表のname
列の格納方法を示します。
上の図では、CUには7行のみが含まれています。Cadillac
やAudi
など、このCU内のすべての非重複値には、Cadillac
の場合は2
、Audi
の場合は0
というように、異なるディクショナリ・コードが割り当てられます。CUには、元の値ではなくディクショナリ・コードが格納されます。
ノート:
データベースで結合グループのために共通ディクショナリが使用される場合、ローカル・ディクショナリには、記号ではなく共通ディクショナリへの参照が含まれます。たとえば、ローカル・ディクショナリには、vehicles.name
列の値Audi
、BWM
およびCadillac
が格納されるのではなく、101
、220
および66
などのディクショナリ・コードが格納されます。
CUヘッダーには、列の最小値および最大値が含まれます。この例では、最小値はAudi
で、最大値はCadillac
です。ローカル・ディクショナリには、Audi
、BMW
およびCadillac
という非重複値のリストが格納されます。それらの対応するディクショナリ・コード(0
、1
および2
)は暗黙的です。各IMCU内のCUのローカル・ディクショナリは、他のIMCU内のローカル・ディクショナリから独立しています。
問合せによってAudi社の自動車でフィルタする場合、データベースでは、0
のコードのみについて、このIMCUがスキャンされます。
関連トピック
関連項目:
2.2.1.3 インメモリー記憶域索引
すべてのIMCUヘッダーでは、そのCUのためのインメモリー記憶域索引(IM記憶域索引)が自動的に作成および管理されます。IM記憶域索引では、IMCU内のすべての列の最小値および最大値が格納されます。
たとえば、sales
がIM列ストアに移入されるとします。この表のためのすべてのIMCUには、すべての列が含まれています。sales.prod_id
列は、すべてのIMCU内の別個のCUに格納されます。IMCUヘッダーには、各prod_id
CU (および他のすべてのCU)の最小値および最大値が含まれています。
不要なスキャンをなくすには、データベースで、SQLフィルタ述語に基づいてIMCUプルーニングを実行します。次の図のWHERE prod_id > 14 AND prod_id < 29
例に示すように、データベースでは問合せの述語を満たすIMCUのみをスキャンします。
2.2.2 スナップショット・メタデータ単位(SMU)
スナップショット・メタデータ単位(SMU)には、関連するIMCUのメタデータおよびトランザクション情報が含まれます。
この項では、次の項目について説明します。
2.2.2.1 IMCUとSMU
インメモリー領域の列プールには、IMCUおよびIMEUという実データが格納されます。インメモリー領域内のメタデータ・プールには、SMUが格納されます。
すべてのIMCUは、別個のSMUにマップされます。したがって、列データ・プールに100個のIMCUが含まれる場合、メタデータ・プールには100個のSMUが含まれます。SMUには、関連付けられているIMCUについて、次のようないくつかのタイプのメタデータが格納されます。
-
オブジェクト番号
-
列番号
-
行のマッピング情報
2.2.2.2 トランザクション・ジャーナル
すべてのSMUには、トランザクション・ジャーナルが含まれます。データベースでは、トランザクション・ジャーナルを使用して、IMCUに関するトランザクションの一貫性が保たれます。
データベースでは、IM列ストアが有効になっていない場合と同様に、バッファ・キャッシュを使用してDMLが処理されます。たとえば、UPDATE
文で、IMCU内の行を変更するとします。このケースでは、データベースにより、変更した行のROWIDがトランザクション・ジャーナルに追加され、それがDML文のSCNの時点で失効とマークされます。問合せで新しいバージョンの行にアクセスする必要がある場合は、データベースにより、データベース・バッファ・キャッシュからその行が取得されます。
データベースでは、列、トランザクション・ジャーナルおよびバッファ・キャッシュの内容をマージすることで、読取り一貫性が実現されます。再移入中にIMCUがリフレッシュされた場合は、問合せで、IMCUから直接、最新の行にアクセスできます。
関連項目:
どのようにIM列ストアでトランザクションの一貫性が維持されるかの詳細は、IM列ストアの再移入の最適化を参照してください。
2.2.3 インメモリー式単位(IMEU)
インメモリー式単位(IMEU)は、マテリアライズされたインメモリー式(IM式)、およびユーザーが定義した仮想列のための記憶域コンテナです。
データベースではマテリアライズされた式が、IMCUの他の列と同様に取り扱われます。概念的には、IMEUは、その親IMCUの論理拡張です。IMCUに複数の列を含むことができるのと同様に、IMEUには複数の仮想列を含むことができます。
すべてのIMEUは1つのIMCUのみにマップされ、同じ行セットにマップされます。IMEUには、関連付けられているIMCU内に含まれたデータについて式結果が含まれます。IMCUが移入されると、関連付けられているIMEUも移入されます。
一般的なIM式には、1つ以上の列が含まれており、定数が使用されている場合もあります。また、表内の行と1対1でマップされています。たとえば、employees
表のIMCUに、列weekly_salary
の行1から1000が含まれているとします。このIMCUに格納されている行について、IMEUで、自動検出されたIM式weekly_salary*52
、およびweekly_salary*12
として定義されているユーザー定義の仮想列quarterly_salary
が計算されます。IMCU内の3番目の行は、IMEU内の3番目の行にマップされます。
IMEUは、特定セグメントのIMCUの論理拡張です。デフォルトでは、IMEUは、基本セグメントから、DISTRIBUTE
やDUPLICATE
などのOracle Real Application Clusters (Oracle RAC)プロパティを含むINMEMORY
句プロパティを継承します。IMEU内の記憶域に対して仮想列を有効または無効にすることを選択できます。様々な列に対して圧縮レベルを指定することもできます。
関連トピック
2.3 式統計ストア(ESS)
式統計ストア(ESS)は、式評価についての統計を格納するためにオプティマイザによって保持されるリポジトリです。ESSはSGAにあり、ディスクに保持されます。
IM列ストアが有効になっている場合、データベースでは、そのインメモリー式(IM式)機能のためにESSが利用されます。ただし、ESSは、IM列ストアから独立しています。ESSは、データベースの永続的コンポーネントであり、無効にはできません。
データベースでは、ESSを使用して、式がホット(頻繁にアクセスされている)かどうか、ひいてはIM式の候補が判断されます。問合せのハード解析の間には、ESSにより、SELECT
リスト、WHERE
句、GROUP BY
句などに含まれているアクティブな式が探されます。
ESSにより、セグメントごとに次のような式統計が保持されます。
-
実行頻度
-
評価コスト
-
タイムスタンプ評価
オプティマイザにより、コストおよび評価された回数に基づいて、各式に重み付きのスコアが割り当てられます。値は、正確ではなく概算となります。アクティブな式ほど、高いスコアとなります。ESSでは、最も頻繁にアクセスされた式について内部リストが保持されます。
DBMS_INMEMORY_ADMIN
パッケージを使用して、IM式の挙動を制御します。たとえば、IME_CAPTURE_EXPRESSIONS
プロシージャは、データベースに、データベース内の最もホットな式を特定して徐々に移入するよう求めます。IME_POPULATE_EXPRESSIONS
プロシージャは、データベースに、すぐに式を移入するよう強制します。
ESS情報は、データ・ディクショナリに格納され、DBA_EXPRESSION_STATISTICS
ビューで公開されます。このビューでは、オプティマイザによってESSに収集されたメタデータが示されます。IM式は、SYS_IME
という文字列で接頭辞が付けられ、DBA_IM_EXPRESSIONS
ビューで、システム生成の仮想列として公開されます。
関連項目:
-
「IM式について」
-
ESSについてさらに学習するには、Oracle Database SQLチューニング・ガイドを参照
-
DBA_EXPRESSION_STATISTICS
ビューについてさらに学習するには、Oracle Databaseリファレンスを参照 -
DBMS_INMEMORY_ADMIN
パッケージについてさらに学習するには、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照
2.4 インメモリー・プロセスのアーキテクチャ
サーバー・プロセスは、問合せおよびDMLに応答して、列データをスキャンし、SMUメタデータを更新します。バックグラウンド・プロセスは、ディスクからIM列ストアに行データを移入します。
この項では、次の項目について説明します。
2.4.1 インメモリー・コーディネータ・プロセス(IMCO)
インメモリー・コーディネータ・プロセス(IMCO)では、IM列ストアのための多くのタスクが管理されます。その主要タスクは、列データのバックグラウンド移入および再移入の開始です。
移入はストリーミング・メカニズムであり、行データを列形式に変換してから、それを圧縮します。IMCOにより、NONE
以外の任意の優先順位で、自動的にINMEMORY
オブジェクトの移入が開始されます。優先順位がNONE
のオブジェクトがアクセスされた場合は、IMCOにより、領域管理ワーカー・プロセス(Wnnn)のプロセスを使用してそれらが移入されます。
また、IMCOバックグラウンド・プロセスでは、IM列ストア・オブジェクトが失効しきい値に達したときに、それらのしきい値ベース再移入が開始されます。IMCOでは、失効エントリが存在するが失効しきい値に満たないIM列ストア内の任意のIMCUに対して、トリクル再移入を引き起こす場合があります。
トリクル再移入はバックグラウンドで自動的に行われます。ステップは次のとおりです。
-
IMCOが起動します。
-
IMCOでは、IMCUに失効エントリが存在するかどうかも含めて、移入タスクを実行する必要性の有無が判断されます。
-
IMCOで失効エントリが見つかった場合、領域管理ワーカー・プロセスがトリガーされてこれらのエントリがIMCUで再移入されます。
-
IMCOは2分間スリープしてから、ステップ1に戻ります。
関連項目:
-
バックグラウンド・プロセスについてさらに学習するには、『Oracle Databaseリファレンス』を参照
2.4.2 領域管理ワーカー・プロセス(Wnnn)
領域管理ワーカー・プロセス(Wnnn)は、IMCOにかわってデータを移入または再移入します。
移入中に、Wnnnプロセスは、IMCU、SMUおよびIMEUを作成する役割を担います。IMEUの作成時は、ワーカー・プロセスにより、次のようなタスクが実行されます。
-
移入のための仮想列を特定する
-
仮想列値を作成する
-
各行の値を計算し、データを列形式に変換し、それを圧縮する
-
オブジェクトを領域レイヤーに登録する
-
IMEUをそれらの対応するIMCUに関連付ける
ノート:
IMEUを作成する間も、親IMCUは、引き続きキューで使用可能です。
再移入中は、Wnnnプロセスにより、既存のIMCUおよびトランザクション・ジャーナルに基づいて、IMCUの新しいバージョンが作成され、古いバージョンは一時的に保持されます。このメカニズムは、ダブル・バッファリングと呼ばれます。
データベースは、IM列ストアの内外にIM式を迅速に移動できます。たとえば、IMCUがIMEUなしで作成された場合、データベースは、IMCUに再移入メカニズム全体を強制的に経験させることなく、後でIMEUを追加できます。
INMEMORY_MAX_POPULATE_SERVERS
初期化パラメータは、移入のために開始できる、ワーカー・プロセスの最大数を制御します。INMEMORY_TRICKLE_REPOPULATE_PERCENT
初期化パラメータは、ワーカー・プロセスがトリクル再移入を実行できる回数の最大パーセンテージを制御します。
関連項目:
-
バックグラウンド・プロセスについてさらに学習するには、『Oracle Databaseリファレンス』を参照
2.4.3 In-Memory動的スキャン
In-Memory動的スキャン(IM動的スキャン)は、軽量スレッドを使用して、インメモリー表スキャンをパラレル化します。
この項では、次の項目について説明します。
2.4.3.1 IM動的スキャンの目的
追加のCPUが使用可能な場合、IM動的スキャンは、CPUにバインドされたインメモリー表スキャンを高速化します。
IM動的スキャンは、自動的にアイドル状態のCPUリソースを使用してIMCUを並行してスキャンし、CPU使用率を最大化します。CPUリソースが使用可能な場合、アプリケーションはより高速な分析問合せ結果を自動的に取得できます。スキャンは動的なため、既存のワークロードに影響を与えずに余分なCPU帯域幅を使用できます。
IM動的スキャンは、従来のOracleのパラレル実行よりも柔軟性がありますが、相互に排他的ではありません。動的スキャンは、プロセス内で複数の軽量スレッドの実行を使用します。通常、動的スキャンのパフォーマンス・オーバーヘッドは少なくなっています。
関連項目:
リソース・マネージャについてさらに学習するには、Oracle Database管理者ガイドを参照
2.4.3.2 IM動的スキャンの仕組み
IM動的スキャンは、IMCUを並行して読み取ることで最適なパフォーマンスを実現します。
この項では、次の項目について説明します。
2.4.3.2.1 軽量スレッドについて
軽量スレッドは、全表スキャンをパラレル化するために役立つ実行エンティティです。Oracleプロセスのメモリー・オーバーヘッドが増えないため「軽量」です。
ノート:
IM動的スキャンで使用される軽量スレッドは、マルチスレッドOracle Databaseモデルの通常スレッドと同じではありません。
軽量スレッドは、一連のIMCUのスキャンを調整する、表スキャンプロセスという親フォアグラウンドまたはPQプロセスのリソースを共有します。スレッドは独自の独立した実行フローを維持します。データベースは、スレッドの優先度付けと非同期実行によってスキャンをパラレル化できます。
対象となる問合せの場合、プロセスはスレッドのプールを割り当てます。リソース・マネージャは、データベース・ホストのCPU数およびシステムでの現在の負荷に基づいてプール内のスレッド数を自動的に決定します。アイドル時間が内部しきい値に達して、その時点でデータベースがスレッドを終了しないかぎり、スレッドのプールは後続の問合せのためにセッションで使用可能なままです。
スレッド間の通信は、プロセス内で排他的に発生します。このため、データベース・インスタンス・レベルで競合は発生しません。
関連項目:
マルチスレッドOracle Databaseモデルについて学習するには、Oracle Database概要を参照
2.4.3.2.2 データベースがIM動的スキャンを考慮する場合
軽量スレッドは、CPUリソース・プランが有効で(たとえば、RESOURCE_MANAGER_PLAN=DEFAULT_PLAN
)、データベースのCPU使用率が低い場合に有効になります。
軽量スレッドが有効な場合、データベースは、現在IM列ストアに移入されているオブジェクトをアプリケーションが問い合せたときに、IM動的スキャンを考慮します。通常、シリアルまたはパラレル問合せは、次の特性を持つ場合にIM動的スキャンの候補となります。
-
多数のIMCUまたは列にアクセスする
-
表内のすべての行を消費する
-
CPUに負担がかかる
Oracle Database Resource Manager (リソース・マネージャ)は、INMEMORY_SIZE
が0
より大きい場合に自動的に有効化されます。また、IM動的スキャンに必要です。リソース・マネージャは、軽量スレッドを使用するタイミングと方法を決定します。軽量スレッドは、未使用のリソースを利用しているため、データベース内で最も優先度の低い操作です。
ノート:
IM動的スキャンを実行するには、CPU_COUNT
が24
以上である必要があります。
2.4.3.2.3 IM動的スキャンの仕組み
リソース・マネージャが軽量スレッドを割り当てて、IMCUのスキャンをパラレル化します。
問合せがIM動的スキャンによる利益を得られるとデータベースが判断した場合、通常は次のように進みます。
-
表スキャン・プロセスが、軽量スレッドのプールを生成します。
-
表スキャン・プロセスは、スキャンが必要なすべてのIMCU用に個別のタスクを作成した後、各タスクをタスク・キューに追加します。
-
リソース・マネージャが、表スキャンに参加できるスレッド数を決定します。
-
アクティブ・スレッドがタスク・キューからタスクを選択し、表スキャン・プロセスは完了したタスクの結果を消費します。
データベースの負荷に応じて、リソース・マネージャは問合せの実行中にアクティブな軽量スレッドの数を継続して調整します。 CPUリソースが使用できない場合、表スキャン・プロセスは軽量スレッドを使用せずにスキャンを実行します。
次の図は、sales
表内の12個のIMCUのIM動的スキャンを示しています。
前の図では、データベース・ホストに8つのCPUコアがあります。内部アルゴリズムに基づいて、リソース・マネージャは4つのスレッドを割り当てて表スキャン・プロセスを支援します。このシナリオでは、4つのCPUコアが他の同時データベース操作で使用するためにアイドル状態のままになります。
2.4.3.3 IM動的スキャンのインタフェース
IM動的スキャンは透過的です。これは、アプリケーションの変更を必要としないことを意味し、リソース・マネージャによって自動的に制御されます。
IM動的スキャンは、リソース・マネージャが有効な場合にのみ有効になります。特定のリソース・プランは必要ありません。
いくつかの新しいセッション統計が、IM動的スキャンの使用状況を追跡します。各スレッドは、トレース・データを別のトレース・ファイルに書き込みます。
実行計画は変更されていません。次の図に、実行計画のサンプルを示します。
SQL> SELECT MAX(l_quantity) largest_order FROM lineitem;
LARGEST_ORDER
-------------
50
Elapsed: 00:00:03.41
Execution Plan
----------------------------------------------------------
Plan hash value: 1885658499
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |Cost(%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 116K (4)| 00:00:05 | | |
| 1 | SORT AGGREGATE | | 1 | 3 | | | | |
| 2 | PARTITION RANGE ALL | | 600M | 1716M | 116K (4)| 00:00:05 | 1 | 84 |
| 3 | TABLE ACCESS INMEMORY FULL| LINEITEM | 600M | 1716M | 116K (4)| 00:00:05 | 1 | 84 |
------------------------------------------------------------------------------------------------------
NAME VALUE
-------------------------------------------------------
IM scan CUs memcompress for query low 1147
IM scan bytes in-memory 5.1790E+10
IM scan bytes uncompressed 7.6722E+10
IM scan CUs columns accessed 1147
IM scan rows 600037902
IM scan rows projected 29
IM scan (dynamic) rows 600037902
IM scan (dynamic) multi-threaded scans 1
IM scan (dynamic) tasks processed by thread 1146
計画の特性を考えてみます。
-
実行計画は変更されていません。
計画では、ステップ3でIM動的スキャンに言及していないので注意してください。ただし、SQLモニター・レポートの双眼鏡アイコンをクリックすると、「スレッドの動的スキャン・タスク」が表示されます。
-
IM scan (dynamic) multi-threaded scans
がゼロ以外の場合、データベースがIM動的スキャンを使用したことを意味します。 -
IM scan CUs memcompress for query low
は、lineitem
表に1147個のIMCUが存在することを示しています。 -
IM scan (dynamic) tasks processed by thread
は、並列処理されたIMCUの数を示しています。その数は1146で、
IM scan CUs memcompress for query low
で示されている1147の合計数より少ない数です。データベースは、パラレル化なしで最初のIMCUを分析して、パラレル化に価値があるかどうかを判断しました。答えは「はい」であったため、データベースは残りの1146個のIMCUを並行してスキャンしました。 -
IM scan (dynamic) rows
およびIM scan rows are equal
は、スレッドで問合せのすべての行が取得されたことを意味します。
関連項目:
-
リソース・マネージャを有効にする方法を学習するには、Oracle Database管理者ガイドを参照
-
インメモリー統計の詳細は、Oracle Databaseリファレンスを参照
2.5 CPUアーキテクチャ: SIMDベクター処理
IM列ストアに移入されるデータについて、データベースはSIMD (単一命令、複数データ)ベクター処理を使用します。
IM列ストアでは、CPUでベクター・レジスタにロードして評価できる、列エントリの数が最大化されます。列内の各エントリを1回に1つずつ評価するかわりに、データベースは単一のCPU命令で列値のセットを評価します。SIMDベクター処理により、データベースで、1秒当たり何十億もの行をスキャンできるようになります。
たとえば、promo_id
値に9999
を使用した、sales
表内の注文の総数を確認する問合せをアプリケーションが発行します。sales
表は、IM列ストア内に存在します。問合せでは、まず、次の図に示すようにsales.promo_id
列のみがスキャンされます。
CPUではデータが次のように評価されます。
-
promo_id
列の最初の8つの値(値の数はデータ型と圧縮モードによって異なる)がSIMDレジスタにロードされ、単一の命令で9999
という値と比較されます。 -
エントリが破棄されます。
-
別の8つの値がSIMDレジスタにロードされ、すべてのエントリが評価されるまでこのように続きます。
この項では、次の項目について説明します。
2.5.1 SIMDおよびOracle LOB
Oracleデータベース18cは、特定のLOB列に対するSQL演算子を含む問合せに対するSIMDベクター・サポートを提供します。
サポートの内容は、LOBの種類によって異なります。
-
インラインLOB
IM列ストアは、IMCU内の4KB未満のLOBであるインラインLOBに対して連続した記憶域を提供します。列型記憶域により、データベース・バッファ・キャッシュからLOBデータをアセンブルするオーバーヘッドを排除することで、より高速な問合せ処理が可能です。
-
アウトラインLOB
この場合、IM列ストアは40バイトのLOBロケータのみを格納します。アウトライン列は、列の最適化による利益を得られません。
前述のルールには、例外が1つあります。IMEUは、LOBデータ型として定義されたJSON列に対して最大32KBの連続した記憶域を割り当てることができます。IMEUは、これらの列をOSON形式で格納します。これにより、SIMD処理を使用してより高速な問合せのパフォーマンスを提供できます。
関連項目:
LOBについてさらに学習するには、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイドを参照してください。
2.5.2 SIMDおよびOracle Numbers
QUERY LOW
で表を圧縮する場合、NUMBER
列は、ハードウェアでのネイティブ計算が有効になる最適化された形式を使用してエンコードされます。
SIMDベクター処理では、単純な集計、GROUP BY
集計、算術演算を使用でき、大きいメリットがあります。パフォーマンスの向上は、集計が算術計算に費やす時間によって異なります。集計によっては、最大9倍までの効果があります。
2.5.3 SIMDおよびExadataスマート・フラッシュ・キャッシュ
ハイブリッド列圧縮形式でデータを格納する他、Exadataスマート・フラッシュキャッシュはデータを純粋な列形式で格納できます。
Exadata Smart ScanはSIMD述語をサポートします。利点は、インメモリーのパフォーマンスがDRAM記憶域から二次記憶域に及ぶことです。
デフォルトでは、Exadataスマート・フラッシュ・キャッシュは、レベルMEMCOMPRESS FOR CAPACITY LOW
を使用してデータを圧縮します。圧縮レベルを変更するか、列形式を完全に無効にするには、ALTER TABLE ... NO CELLMEMORY
文を使用します。