16 メモリー・アーキテクチャ
この章では、データベース・インスタンスのメモリー・アーキテクチャについて説明します。
この章の構成は、次のとおりです。
関連項目:
メモリーの構成方法および管理方法は、Oracle Database管理者ガイドを参照してください
Oracle Databaseのメモリー構造の概要
インスタンスが開始されると、Oracle Databaseによってメモリー領域が割り当てられ、バックグラウンド・プロセスが起動されます。
メモリー領域には、次のような情報が格納されています。
-
プログラム・コード
-
接続されているセッションについての情報(現在はアクティブかどうかは不問)
-
プログラムの実行時に必要な情報(行をフェッチしている問合せの現在の状態など)
-
プロセス間で共有および通信されるロック・データなどの情報
-
データ・ブロックやREDOレコードなどの、ディスク上にも存在するキャッシュ・データ
関連項目:
基本的なメモリー構造
Oracle Databaseには、それぞれに複数のサブコンポーネントを含む、複数のメモリー領域があります。
Oracle Databaseに関連する基本的なメモリー構造は、次のような領域で構成されています。
-
システム・グローバル領域(SGA)
SGAは、SGAコンポーネントと呼ばれる共有メモリー構造のグループで、1つのOracle Databaseインスタンスに関するデータと制御情報が保存されています。すべてのサーバーとバックグラウンド・プロセスでSGAを共有します。SGAに格納されるデータには、キャッシュ・データ・ブロックや共有SQL領域などがあります。
-
プログラム・グローバル領域(PGA)
PGAは、Oracleプロセス専用のデータや制御情報を含む、非共有メモリー領域です。Oracle Databaseでは、Oracleプロセスの起動時にPGAが作成されます。
PGAは、サーバー・プロセスごと、およびバックグラウンド・プロセスごとに存在します。個々のPGAの集合は、合計インスタンスPGAまたはインスタンスPGAと呼ばれています。個々のPGAではなく、データベース初期化パラメータを使用してインスタンスPGAのサイズを設定します。
-
ユーザー・グローバル領域(UGA)
UGAは、ユーザー・セッションに関連付けられたメモリーです。
-
ソフトウェア・コード領域
ソフトウェア・コード領域とは、実行中または実行される可能性のあるコードを格納するためのメモリー部分です。Oracle Databaseのコードはソフトウェア領域に格納され、通常、この場所はユーザー・プログラムの格納場所とは異なり、より排他的で保護されています。
次の図に、これらのメモリー構造の関係を示します。
Oracle Databaseのメモリー管理
メモリー管理では、データベースの変化に応じて、Oracleインスタンスのメモリー構造を最適なサイズに維持します。Oracle Databaseでは、メモリー関連の初期化パラメータの設定に基づいてメモリーが管理されます。
メモリー管理の基本的なオプションは、次のとおりです。
-
自動メモリー管理
データベース・インスタンス・メモリーのターゲット・サイズを指定します。インスタンスは自動的にターゲット・メモリー・サイズにチューニングされ、必要に応じて、SGAとインスタンスPGAとの間でメモリーの再配分が行われます。
-
自動共有メモリー管理
この管理モードでは、一部の処理が自動化されます。SGAは、ターゲット・サイズを設定し、PGAは、ターゲット・サイズの合計を設定するか、作業領域を個別に管理できます。
-
手動メモリー管理
合計メモリー・サイズを設定するかわりに、SGAのコンポーネントおよびインスタンスPGAを個別に管理するための数多くの初期化パラメータを設定します。
Database Configuration Assistant(DBCA)を使用してデータベースを作成し、基本インストール・オプションを選択した場合のデフォルトは、自動メモリー管理です。
関連項目:
-
DBCAの詳細は、Oracle Database 2日でデータベース管理者を参照してください
-
DBAのメモリー管理オプションの詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
-
メモリー管理オプションの詳細は、『Oracle Database管理者ガイド』を参照してください
ユーザー・グローバル領域の概要
UGAはセッション・メモリーで、ログオン情報やデータベース・セッションに必要なその他の情報などのセッション変数に割り当てられるメモリーです。基本的に、UGAにはセッション状態が格納されています。
次の図に、UGAを示します。
セッションによってPL/SQLパッケージがメモリーにロードされると、特定の時点においてすべてのパッケージ変数に格納されている値のセットであるパッケージ状態がUGAに格納されます。パッケージのサブプログラムによって変数が変更されると、パッケージ状態も変更されます。デフォルトで、パッケージ変数はセッションの存続期間に対して固有の変数であり、セッションの存続期間中保持されます。
UGAには、OLAPページ・プールも格納されています。このプールでは、OLAPデータ・ページが管理され、データ・ページはデータ・ブロックと同じものです。ページ・プールは、OLAPセッションの開始時に割り当てられて、セッションの終了時に解放されます。OLAPセッションは、ユーザーがキューブなどのディメンション・オブジェクトを問い合せると、常に自動的に開かれます。
データベース・セッションの存続期間中は、セッションでUGAが使用可能である必要があります。このことは、PGAは単一のプロセス固有の領域であるため、共有サーバー接続を使用する場合にはUGAをPGAに格納できないことを意味しています。したがって、共有サーバー接続を使用する場合は、すべての共有サーバー・プロセスからUGAにアクセスできるよう、UGAはSGAに格納されます。専用サーバー接続を使用する場合は、UGAはPGAに格納されます。
関連項目:
-
共有サーバー接続の詳細は、Oracle Database Net Services管理者ガイドを参照してください
-
Oracle OLAPの概要は、『Oracle OLAPユーザーズ・ガイド』を参照してください。
プログラム・グローバル領域(PGA)の概要
PGAは、システムの他のプロセスやスレッドによって共有されていない、動作中のプロセスやスレッドに固有のメモリーです。PGAはプロセス固有であるため、SGA内で割り当てられることはありません。
PGAは、専用サーバー・プロセスまたは共有サーバー・プロセスが必要とするセッション依存の変数を含むメモリー・ヒープです。サーバー・プロセスでは、必要なメモリー構造がPGA内に割り当てられます。
PGAは、文書係が使用するカウンタ上の一時的な作業領域に似ています。このたとえの場合、文書係はサーバー・プロセスを表しており、顧客(クライアント・プロセス)のために作業を行います。文書係は、作業のための場所をカウンタ上に準備し、その場所に顧客のリクエストの詳細をまとめ、顧客が要求するフォルダをソートし、作業が終わるとその場所を解放します。
次の図に、共有サーバー用に構成されていないインスタンスのインスタンスPGA (すべてのPGAの集合)を示します。初期化パラメータを使用して、インスタンスPGAの最大ターゲット・サイズを設定できます。個々のPGAでは、必要に応じて最大このターゲット・サイズまでサイズを増加できます。
注意:
バックグラウンド・プロセスにも独自のPGAが割り当てられます。ここでは、サーバー・プロセスPGAのみを説明します。
関連項目:
PGAメモリー管理の概要は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
PGAの内容
PGAは、それぞれ異なる目的を持つ複数の領域によって構成されています。
次の図に、専用サーバー・セッションのPGAの内容を示します。どの場合にもすべてのPGA領域が揃っているとはかぎりません。
プライベートSQL領域
プライベートSQL領域には、解析済のSQL文に関する情報と、処理に使用するその他のセッション固有の情報が保持されます。
サーバー・プロセスでSQLまたはPL/SQLのコードが実行される場合、プロセスではプライベートSQL領域を使用してバインド変数値、問合せ実行状態情報、問合せ実行作業領域が格納されます。
PGA内のプライベートSQL領域は、SGAにおいて実行計画が格納される共有SQL領域とは異なります。同じセッション内または異なるセッション内の複数のプライベートSQL領域から、SGA内の単一の実行計画を指すことができます。たとえば、あるセッションにおけるSELECT * FROM sales
の20回の実行および別のセッションにおける同じ問合せの10回の実行において、同じ計画を共有できます。各実行におけるプライベートSQL領域は共有されず、異なる値やデータが含まれている可能性があります。
カーソルは、特定のプライベートSQL領域の名前またはハンドルです。次の図に示すように、カーソルはクライアントから見るとポインタ、サーバーから見ると状態のようなものです。カーソルはプライベートSQL領域と密接に関連しているため、これらの用語は同じ意味で使用されることがあります。
プライベートSQL領域は、次の領域によって構成されています。
-
ランタイム領域
この領域には、問合せ実行状態情報が含まれています。たとえば、ランタイム領域では、全表スキャンで現在までに取得された行数が追跡されます。
Oracle Databaseでは、ランタイム領域は実行要求の最初の処理で作成されます。DML文では、SQL文が終了するとランタイム領域が解放されます。
-
持続領域
この領域には、バインド変数値が含まれています。バインド変数値は、SQL文が実行される実行時にSQL文に指定されます。持続領域は、カーソルのクローズ時にのみ解放されます。
クライアント・プロセスは、プライベートSQL領域の管理を担当します。クライアント・プロセスが割り当てることのできるプライベートSQL領域の数は、初期化パラメータOPEN_CURSORS
によって制限されますが、プライベートSQL領域の割当ておよび割当て解除は、アプリケーションに大きく依存します。
ほとんどのユーザーはデータベース・ユーティリティの自動カーソル処理を使用しますが、Oracle Databaseのプログラム・インタフェースを利用すると、開発者はカーソルをより制御できるようになります。一般的に、持続領域を解放し、アプリケーション・ユーザーが必要とするメモリーを最小限に抑えるには、オープンされているカーソルのうち再利用しないすべてのカーソルをアプリケーション側でクローズする必要があります。
関連項目:
-
「共有SQL領域」
-
カーソルの使用方法の詳細は、Oracle Database開発ガイドおよびOracle Database PL/SQL言語リファレンスを参照してください
SQL作業領域
作業領域とは、メモリー集中型の操作に使用されるPGAメモリーを個別に割り当てるための領域です。
たとえば、ソート演算子では、ソート領域を使用して行のセットがソートされます。同様に、ハッシュ結合演算子ではハッシュ領域を使用して左側の入力からハッシュ表が構築され、ビットマップ・マージ演算子ではビットマップ・マージ領域を使用して複数のビットマップ索引のスキャンにより取得されたデータがマージされます。
次の例では、employees
およびdepartments
の結合をその問合せ計画とともに示しています。
SQL> SELECT *
2 FROM employees e JOIN departments d
3 ON e.department_id=d.department_id
4 ORDER BY last_name;
.
.
.
--------------------------------------------------------------------------------
| Id| Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 106 | 9328 | 7 (29)| 00:00:01 |
| 1 | SORT ORDER BY | | 106 | 9328 | 7 (29)| 00:00:01 |
|*2 | HASH JOIN | | 106 | 9328 | 6 (17)| 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPARTMENTS | 27 | 540 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| EMPLOYEES | 107 | 7276 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------
前述の例では、ランタイム領域で全表スキャンの進行状況が追跡されます。セッションでは、ハッシュ領域を使用してハッシュ結合が実行されて、2つの表の行が照合されます。ORDER BY
によるソートは、ソート領域で行われます。
演算子で処理するデータが作業領域に収まらない場合は、Oracle Databaseによって入力データがより小さく分割されます。データベースでは、このようにして一部のデータがメモリー内で処理され、残りのデータは後で処理するために一時ディスク記憶域に格納されます。
自動PGAメモリー管理が有効になっている場合、作業領域サイズはデータベースにより自動的にチューニングされます。作業領域のサイズを手動で制御してチューニングすることもできます。
通常、作業領域を増やすとメモリー使用率は増えますが、演算子のパフォーマンスが大幅に改善されます。作業領域は、入力データや関連するSQL演算子によって割り当てられる補助メモリー構造を格納するために十分なサイズにすることをお薦めします。十分なサイズが確保されていない場合は、一部の入力データがディスクにキャッシュされるため、レスポンス時間が長くなります。作業領域のサイズが入力データ・サイズに比べて非常に小さい場合は、データを分割して何度も渡すことが必要となるため、レスポンス時間が大幅に長くなります。
関連項目:
-
自動PGA管理の使用方法の詳細は、Oracle Database管理者ガイドを参照してください
-
PGAメモリーのチューニング方法の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
専用サーバー・モードおよび共有サーバー・モードにおけるPGAの使用
PGAにメモリーが割り当てられるかどうかは、データベースで専用サーバー接続が使用されるか、共有サーバー接続が使用されるかに応じて異なります。
次の表にこの相違を示します。
表16-1 専用サーバーと共有サーバーのメモリー割当て方法の相違点
メモリー領域 | 専用サーバー | 共有サーバー |
---|---|---|
セッション・メモリーの性質 |
プライベート |
共有 |
持続領域の位置 |
PGA |
SGA |
DMLおよびDDL文のランタイム領域の位置 |
PGA |
PGA |
関連項目:
共有サーバーを使用するためのデータベースの構成方法の詳細は、『Oracle Database管理者ガイド』を参照してください。
システム・グローバル領域(SGA)の概要
SGAは、Oracleバックグラウンド・プロセスとともにデータベース・インスタンスを構成する、読取り/書込み可能なメモリー領域です。
注意:
サーバー・プロセスおよびバックグラウンド・プロセスは、SGA内ではなく、別のメモリー領域内に存在しています。
ユーザー用に実行されるすべてのサーバー・プロセスで、インスタンスSGA内の情報の読取りが可能です。データベース操作中にSGAに書き込むプロセスもあります。
各データベース・インスタンスには、独自のSGAがあります。Oracle Databaseでは、インスタンスの開始時にSGAのメモリーが自動的に割り当てられて、インスタンスが停止するとメモリーが再利用されます。SQL*PlusまたはOracle Enterprise Managerを使用してインスタンスを開始した場合、SGAは次の例に示すサイズになります。
SQL> STARTUP
ORACLE instance started.
Total System Global Area 368283648 bytes
Fixed Size 1300440 bytes
Variable Size 343935016 bytes
Database Buffers 16777216 bytes
Redo Buffers 6270976 bytes
Database mounted.
Database opened.
図16-1に示すように、SGAはいくつかのメモリー・コンポーネントによって構成され、これらのコンポーネントは、特定の種類のメモリー割当て要求を満たすために使用されるメモリーのプールです。REDOログ・バッファを除くすべてのSGAコンポーネントは、グラニュルと呼ばれる連続したメモリーの単位で割当ておよび割当て解除されます。グラニュルのサイズはプラットフォーム固有であり、SGAサイズの合計から決定されます。
SGAコンポーネントの情報は、V$SGASTAT
ビューに問い合せることができます。
次に、最も重要なSGAコンポーネントを示します。
関連項目:
-
グラニュルのサイズ設定の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください
データベース・バッファ・キャッシュ
データベース・バッファ・キャッシュとも呼ばれるデータベース・バッファ・キャッシュとは、データファイルから読み取られたデータ・ブロックのコピーを格納するメモリー領域のことです。
バッファとは、現在使用されているデータ・ブロックまたは最近使用されたデータ・ブロックがバッファ・マネージャによって一時的にキャッシュされるメイン・メモリーのアドレスのことです。データベース・インスタンスに同時接続されたユーザーはすべて、バッファ・キャッシュへのアクセスを共有します。
データベース・バッファ・キャッシュの目的
Oracle Databaseでは、複数の目的でバッファ・キャッシュが使用されます。
目的には次のものがあります。
-
物理I/Oを最適化します。
データベースでは、キャッシュ内のデータ・ブロックが更新されて、REDOログ・バッファに変更についてのメタデータが格納されます。
COMMIT
の後、データベースによってREDOバッファがオンラインREDOログに書き込まれますが、データ・ブロックが即座にデータ・ファイルに書き込まれるわけではありません。かわりに、データベース・ライター(DBW)によって、バックグラウンドで遅延書込みが実行されます。 -
頻繁にアクセスされるブロックをバッファ・キャッシュに保持して、頻繁にアクセスされないブロックはディスクに書き込みます。
データベース・スマート・フラッシュ・キャッシュ(フラッシュ・キャッシュ)を有効にすると、バッファ・キャッシュの一部をフラッシュ・キャッシュ内に保持できます。このバッファ・キャッシュ拡張は、1つ以上のフラッシュ・デバイスに格納されます。フラッシュ・メモリー内にバッファがキャッシュされ、磁気ディスクからの読取りが必要なくなるため、データベースのパフォーマンスが向上します。
DB_FLASH_CACHE_FILE
およびDB_FLASH_CACHE_SIZE
初期化パラメータを使用して、複数のフラッシュ・デバイスを構成します。バッファ・キャッシュでは、各デバイスを追跡し、デバイスに均等にバッファを分配します。注意:
データベース・スマート・フラッシュ・キャッシュは、SolarisおよびOracle Linux環境でのみ使用できます。
-
Oracle永続メモリー・ファイルストア(PMEMファイルストア)のデータ・ファイルを指すバッファ・ヘッダーを管理します
PMEMファイルストアを有効にした場合、データベース・ファイルは直接読取り専用アクセス用にマップされます。問合せでは、従来のバッファ・キャッシュ・メカニズムをバイパスでき、不要なI/Oを回避できます。この場合、バッファ・ヘッダーにはPMEMブロックに対応するメタデータを格納する必要があります。データベースは、変更、読取りの一貫性、およびホット・データ・ブロックへの高速アクセスのために、従来の(DRAM)バッファ・キャッシュを引き続き使用できます。
関連項目:
-
DB_FLASH_CACHE_FILE
初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください
バッファ状態
データベースでは、内部アルゴリズムを使用してキャッシュ内のバッファが管理されます。
バッファには、次のような相互に排他的な状態があります。
-
未使用
このバッファはまだ使用されていないか、現在使用されていないため、使用可能です。このタイプのバッファは、最も使用しやすいバッファです。
-
クリーン
このバッファは過去に使用され、現在はある時点において読取り一貫性があるバージョンのブロックが含まれています。このブロックにはデータが含まれていますが、クリーンであるため、チェックポイントを作成する必要はありません。データベースでは、このブロックを確保して再利用できます。
-
使用済
このバッファには、まだディスクに書き込まれていない変更されたデータが含まれています。データベースでこのバッファを再利用する前に、このブロックのチェックポイントを作成する必要があります。
すべてのバッファには、使用中または使用可能(確保解除)というアクセス・モードがあります。バッファは、ユーザー・セッションによってアクセスされている間にメモリーからエージ・アウトされないように、キャッシュ内で確保されます。確保されたバッファを複数のセッションから同時に変更することはできません。
バッファ・モード
クライアントがデータを要求すると、Oracle Databaseでは、現在のモードまたは一貫したモードいずれかでデータベース・バッファ・キャッシュからバッファが取得されます。
モードの違いは次のとおりです。
-
現在のモード
現在のモード取得は、DBブロック取得とも呼ばれ、バッファ・キャッシュ内の現行のブロックをそのまま取得します。たとえば、コミットされていないトランザクションによってブロック内の2つの行が更新された場合、現行モード取得により、これらのコミットされていない行を含むブロックが取得されます。Oracle Databaseでは、ブロックの現行バージョンのみを更新する必要がある変更文を実行する際に、最も頻繁にDBブロック取得が使用されます。
-
一貫したモード
読取り一貫性取得は、ブロックの読取り一貫性バージョンを取得します。この取得では、UNDOデータが使用される場合があります。たとえば、トランザクションによってブロック内の2つの行が更新されたがまだコミットされていない場合に、別のセッションの問合せがそのブロックを要求すると、Oracle DatabaseではUNDOデータを使用して、コミットされていない更新を含まない、このブロックの読取り一貫性バージョン(読取り一貫性クローンと呼ばれます)が作成されます。一般に、問合せは一貫性モードでブロックを取得します。
関連項目:
-
DBブロック取得や読取り一貫性取得などのデータベース統計の詳細は、Oracle Databaseリファレンスを参照してください
バッファI/O
論理I/Oは、バッファI/Oとも呼ばれ、バッファ・キャッシュ内でのバッファの読取りおよび書込みを表しています。
要求されたバッファがメモリーにない場合、Oracle Databaseは物理I/Oを実行してフラッシュ・キャッシュまたはディスクからメモリーにバッファをコピーします。その後、論理I/Oを実行して、キャッシュされたバッファを読み取ります。
バッファ置換アルゴリズム
効率的にバッファにアクセスできるようにするため、データベースはメモリーにキャッシュするバッファと、ディスクからアクセスするバッファを決定する必要があります。
データベースでは次のアルゴリズムを使用します。
-
LRUベースでブロック・レベルの置換アルゴリズム
この高度なアルゴリズムはデフォルトのアルゴリズムで、使用済バッファと使用済でないバッファへのポインタを含む、最近の使用頻度が最も低い(LRU)リストを使用します。LRUリストにはホット・エンドとコールド・エンドがあります。コールド・バッファは、最近使用されていないバッファです。ホット・バッファは、頻繁にアクセスされ、最近使用されたバッファです。概念的にはLRUは1つのみですが、データベースでは実際にはデータ同時実行性のために複数のLRUが使用されています。
-
温度ベースでオブジェクト・レベルの置換アルゴリズム
Oracle Database 12cリリース1 (12.1.0.2)以降、自動ビッグ・テーブル・キャッシング機能により、表スキャンで次のシナリオに異なるアルゴリズムを使用できるようになりました。
-
パラレル問合せ
単一インスタンスおよびOracle Real Applications Cluster (Oracle RAC)データベースでは、
DB_BIG_TABLE_CACHE_PERCENT_TARGET
初期化パラメータがゼロ以外の値に設定され、PARALLEL_DEGREE_POLICY
がauto
またはadaptive
に設定されている場合、パラレル問合せでビッグ・テーブル・キャッシュを使用できます。 -
シリアル問合せ
単一インスタンス構成の場合のみ、
DB_BIG_TABLE_CACHE_PERCENT_TARGET
初期化パラメータがゼロ以外の値に設定されている場合、シリアル問合せでビッグ・テーブル・キャッシュを使用できます。
表がメモリー内に収まらない場合、データベースはアクセス・パターンに基づいてキャッシュするバッファを決定します。ポピュラーな表の95%しかメモリー内に収まらない場合、データベースは、周期的にブロックをメモリーに読み込んでブロックをディスクに書き込むかわりに(スラッシングと呼ばれる現象)、ブロックの5%をディスクに残す選択を行うことができます。複数のラージ・オブジェクトをキャッシュする際、データベースはよりポピュラーな表は人気がありポピュラーでない表は人気がないと見なし、これはキャッシュするブロックに影響を与えます。
DB_BIG_TABLE_CACHE_PERCENT_TARGET
初期化パラメータは、このアルゴリズムを使用するバッファ・キャッシュの比率を設定します。注意:
このドキュメントでは、LRUベースでブロック・レベルの置換アルゴリズムについて説明します。
-
関連項目:
温度ベースのアルゴリズムの詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照
バッファ書込み
データベース・ライター(DBW)プロセスでは、コールドかつ使用済のバッファが定期的にディスクに書き込まれます。
DBWでは、次の状況でバッファが書き込まれます。
-
サーバー・プロセスで、新しいブロックをデータベース・バッファ・キャッシュに読み取るときにクリーンなバッファが見つからなかった場合。
バッファが使用されるにつれて、使用可能バッファの数が減少します。使用可能バッファの数が内部のしきい値未満になり、クリーンなバッファが必要な場合には、サーバー・プロセスからDBWに対して、書込みを行うように通知されます。
Oracle Databaseでは、LRUを使用して、どの使用済バッファに書き込むかが決定されます。使用済バッファがLRUのコールド・エンドに達すると、そのバッファはLRUから書込みキューに移動されます。DBWによって、可能な場合にはマルチブロック書込みを使用して、キュー内のバッファがディスクに書き込まれます。このメカニズムによって、LRUの終端に使用済バッファが滞留しなくなり、クリーンなバッファを検出して再利用できるようになります。
-
データベースで、REDOスレッド内のインスタンス・リカバリを開始する位置であるチェックポイントを進める必要がある場合。
-
表領域が読取り専用ステータスに変更されたか、オフラインにされた場合。
関連項目:
-
バッファ書込みの問題を診断およびチューニングする方法の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
バッファ読取り
未使用バッファの数が減少したら、データベースにより、バッファ・キャッシュからバッファが削除されます。
アルゴリズムはフラッシュ・キャッシュが有効かどうかに応じて変わります。
-
フラッシュ・キャッシュが無効な場合
各クリーン・バッファは、必要に応じて上書きされ、再使用されます。上書きされたバッファが後から必要になった場合は、そのバッファが磁気ディスクから読み取られます。
-
フラッシュ・キャッシュが有効な場合
DBWがフラッシュ・キャッシュにクリーン・バッファ本体を書き込めるため、インメモリーのバッファの再利用が可能になります。データベースは、フラッシュ・キャッシュ内のバッファ本体の状態と場所を追跡できるように、メイン・メモリー内のLRUリストにバッファのヘッダーを保持します。バッファが後で必要になったときに、データベースは磁気ディスクからではなく、フラッシュ・キャッシュからバッファを読み取ります。
クライアント・プロセスからバッファが要求されると、サーバー・プロセスは最初にバッファ・キャッシュ内でそのバッファを検索します。データベースによるメモリー内のバッファの検索時には、キャッシュ・ヒットの処理が実行されます。検索順序は、次のとおりです。
-
サーバー・プロセスによってバッファ・キャッシュ内にバッファ全体があるかどうかが検索されます。
バッファ全体が見つかった場合は、データベースによってそのバッファの論理読取りが実行されます。
-
サーバー・プロセスによってフラッシュ・キャッシュのLRUリスト内にバッファのヘッダーがあるかどうかが検索されます。
バッファのヘッダーが見つかった場合、データベースによってフラッシュ・キャッシュからインメモリーのキャッシュにバッファ本体の最適化物理読取りが実行されます。
-
キャッシュ・メモリー内にバッファが見つからない場合は(キャッシュ・ミス)、サーバー・プロセスによって次のステップが実行されます。
-
データファイルからメモリーへのブロックのコピー(物理読取り)
-
メモリーに読み取られたバッファの論理読取りの実行
-
図16-6に、バッファの検索順序を示します。拡張バッファ・キャッシュは、バッファ全体を格納するインメモリーのバッファ・キャッシュと、バッファ本体を格納するフラッシュ・キャッシュから構成されます。図では、データベースによってバッファ・キャッシュ内にバッファがあるかどうか検索され、バッファが見つからなければ、磁気ディスクからメモリーにバッファが読み込まれます。
通常、キャッシュにヒットした場合のデータへのアクセスは、キャッシュ・ミスの場合よりも高速です。バッファ・キャッシュ・ヒット率は、要求されたブロックがバッファ・キャッシュ内に見つかり、ディスクからの読取りが不要である確率を示しています。
データファイルまたは一時ファイルから物理読取りが実行されます。データファイルからの読取りの後には、論理I/Oが実行されます。一時ファイルからの読取りは、メモリー不足によってデータベースがデータを一時表に書き込み、後からそのデータを読み取る必要がある場合に行われます。このような物理読取りでは、バッファ・キャッシュにはアクセスされないため、論理I/Oは発生しません。
関連項目:
バッファ・キャッシュ・ヒット率の計算方法の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
バッファのタッチ・カウント
データベースでは、タッチ・カウントを使用して、LRUリスト上のバッファへのアクセス頻度が測定されます。このメカニズムによって、バッファが確保されたときに常にLRUリスト上でバッファをシャッフルするかわりに、カウンタを増加できます。
注意:
メモリー内のブロックは、物理的には移動されません。移動は、リスト上のポインタの位置を変更することによって行われます。
バッファが確保されると、最後にタッチ・カウントが増加された時間が特定されます。カウントが3秒前より以前に増加されている場合は、カウントが増加され、そうでない場合は、カウントはそのままです。この3秒ルールによって、バッファが非常に多くの回数確保されたときに、同じ数だけタッチ・カウントが増加されることを防止できます。たとえば、セッションでデータ・ブロックに複数の行を挿入する場合に、データベースではこれらの挿入が1回のタッチであるとみなされます。
バッファがLRUのコールド・エンドにあり、タッチ・カウントが大きい場合、バッファはホット・エンドに移動されます。タッチ・カウントが小さい場合、バッファはキャッシュからエージ・アウトされます。
バッファ・プール
バッファ・プールとは、バッファの集合のことです。
データベース・バッファ・キャッシュは、1つ以上のバッファ・プールによって構成されていて、これらのバッファ・プールはほとんど同じ方法でブロックを管理します。プールのアルゴリズムは、経過期間ブロックとキャッシュ・ブロックで根本的には異なりません。
バッファ・キャッシュ内のデータを保持するバッファ・プール、または新しいデータがデータ・ブロックを使用した直後に使用可能なバッファを提供するバッファ・プールを手動で個別に構成できます。その後、適切なバッファ・プールに特定のスキーマ・オブジェクトを割り当て、ブロックがキャッシュからエージ・アウトされる方法を制御できます。たとえば、セグメントをホット、ウォームおよびコールド・バッファ・プールに分割することができます。
次のバッファ・プールがあります。
-
DEFAULTプール
このプールは、ブロックが通常キャッシュされる場所です。手動で個別にプールを構成しない場合は、DEFAULTプールが唯一のバッファ・プールとなります。他のプールのオプション構成によって、デフォルト・プールは影響を受けません。
ビッグ・テーブル・キャッシュは温度ベースでオブジェクト・レベルの置換アルゴリズムを使用するDEFAULTプールのオプションのセクションとなっています。単一インスタンスおよびOracle RACデータベースでは、
DB_BIG_TABLE_CACHE_PERCENT_TARGET
初期化パラメータがゼロ以外の値に設定され、PARALLEL_DEGREE_POLICY
がauto
またはadaptive
に設定されている場合、パラレル問合せでビッグ・テーブル・キャッシュを使用できます。単一インスタンス構成の場合のみ、DB_BIG_TABLE_CACHE_PERCENT_TARGET
が設定されている場合、シリアル問合せでビッグ・テーブル・キャッシュを使用できます。 -
KEEPプール
このプールは、頻繁にアクセスされたが、領域が不足したためにDEFAULTプールからエージ・アウトされたブロック用のプールです。KEEPバッファ・プールの目的は、メモリー内にオブジェクトを保存して、I/O操作を避けることにあります。
注意:
KEEPプールは他のプールと同じようにバッファを管理し、バッファをピン留めするために特別なアルゴリズムを使用しません。KEEPという単語は命名規則です。保存する表はより大規模な保存プールに配置し、保存しない表はより小規模なリサイクル・プールに配置できます。
-
RECYCLEプール
このプールは、頻繁に使用されないブロック用のプールです。RECYCLEプールによって、キャッシュ内の領域が不要なオブジェクトによって消費されることを防止できます。
データベースには、標準ブロック・サイズがあります。標準のサイズとは異なるブロック・サイズを持つ表領域を作成できます。非デフォルトのブロック・サイズには、それぞれ独自のプールがあります。Oracle Databaseでは、これらのプールのブロックもDEFAULTプールと同様に管理されます。
次の図に、複数のプールが使用された場合のバッファ・キャッシュの構造を示します。このキャッシュには、DEFAULTプール、KEEPプールおよびRECYCLEプールが含まれています。デフォルトのブロック・サイズは8KBです。このキャッシュには、2KB、4KBおよび16KBという非標準のブロック・サイズを使用する表領域用の個別のプールが含まれています。
関連項目:
-
バッファ・プールの詳細は、Oracle Database管理者ガイドを参照してください
-
複数のバッファ・プールを使用する方法の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
-
DB_BIG_TABLE_CACHE_PERCENT_TARGET
初期化パラメータの詳細は、Oracle Databaseリファレンスを参照してください
バッファと全表スキャン
データベースは複雑なアルゴリズムを使用して表スキャンを管理します。デフォルトでは、バッファをディスクから読み取る必要がある場合、そのバッファはLRUリストの中央に挿入されます。これにより、ホット・ブロックがキャッシュ内に維持されて、再度ディスクから読み取る必要がなくなります。
表の最高水位標(HWM)より下のすべての行を順次読み取る全表スキャンでは、問題が発生します。表セグメント内のブロックの合計サイズが、バッファ・キャッシュのサイズよりも大きいとします。この表を全体スキャンすると、バッファ・キャッシュが一掃されて、頻繁にアクセスされるブロックのキャッシュが維持されなくなる可能性があります。
関連項目:
完全表スキャンのデフォルト・モード
デフォルトでは、データベースは全表スキャンに対して厳密的なアプローチを取り、テーブル・サイズの割合がバッファ・キャッシュに対して小さい場合のみ、小規模な表をメモリーにロードします。
データベースは、中規模の表をキャッシュするかどうか決定するため、最後の表スキャンの間隔、バッファ・キャッシュの経過期間タイムスタンプおよびバッファ・キャッシュに残っている容量を考慮するアルゴリズムを使用します。
通常データベースは、非常に大規模な表に対しては、ダイレクト・パス読取りを使用します。ダイレクト・パス読取りでは、バッファ・キャッシュの移入を避けるため、ブロックが直接PGAにロードされ、SGA全体が省略されます。データベースは、中規模の表に対しては、ダイレクト読取りまたはキャッシュ読取りを使用する場合があります。データベースは、キャッシュ読取りを使用することを決定した場合、スキャンによって実質的にバッファ・キャッシュが一掃されることを防止するために、これらのブロックをLRUの最後に配置します。
Oracle Database 12cリリース1 (12.1.0.2)以降、データベース・インスタンスのバッファ・キャッシュでは自動的に内部計算を実行して、データベースをインスタンスSGAに完全にキャッシュするのに十分なメモリーがあるかどうか、アクセス時に表をキャッシュすることがパフォーマンス上有益かどうかを判断します。データベース全体をメモリー内に完全に収めることができ、他の様々な内部条件が満たされる場合、Oracle Databaseはデータベース内のすべての表を小規模な表として処理し、キャッシュの対象であると見なします。ただし、データベースではNOCACHE
属性が付けられたLOBはキャッシュしません。
パラレル問合せの実行
全表スキャンの実行時、複数のパラレル実行サーバーを使用すると、レスポンス時間が改善されることがあります。
一部の例では、データベースに大量のメモリーがある場合、データベースでは、プログラム・グローバル領域(PGA)へのダイレクト・パス読取りを使用するかわりに、システム・グローバル領域(SGA)にパラレル問合せのデータをキャッシュできます。パラレル問合せは、リソースを使用する可能性があるため、通常では同時実行性の低いデータ・ウェアハウスで実行されます。
関連項目:
-
データ・ウェアハウスの概要は、Oracle Databaseデータ・ウェアハウス・ガイドを参照してください
-
パラレル実行の詳細は、Oracle Database VLDBおよびパーティショニング・ガイドを参照してください
CACHE属性
まれに、デフォルトのキャッシュ動作が望ましくないことがありますが、その場合は、ALTER TABLE ... CACHE
を使用して、大規模な表からデータベース・バッファ・キャッシュにブロックが読み取られる方法を変更できます。
CACHE
属性が設定された表では、データベースはバッファ・キャッシュでブロックを強制またはピン留めしません。かわりに、他の表ブロックと同じようにブロックをキャッシュからエージ・アウトします。このオプションを使用すると、大規模な表の全体スキャンを行ったときに、キャッシュ内の他のほとんどのブロックが一掃される可能性があるため、注意が必要です。
注意:
ALTER TABLE ... CACHE
を実行しても、表はキャッシュされません。
KEEP属性
大規模な表に対しては、ALTER TABLE ... STORAGE BUFFER_POOL KEEP
を使用して、これらの表のブロックをKEEPプールにロードできます。
表をKEEPプールに配置すると、ブロックが保管されているバッファ・キャッシュの部分が変更されます。ブロックは、デフォルト・バッファ・プールにキャッシュされるのではなく、KEEPバッファ・プールにキャッシュされます。KEEPプールのキャッシュを制御する別個のアルゴリズムはありません。
関連項目:
-
CACHE
句およびKEEP
属性の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 -
バッファ・キャッシュ・アドバイザ統計の解析方法の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。
強制全データベース・キャッシュ・モード
状況によっては、パフォーマンスを向上するために、ALTER DATABASE ... FORCE FULL DATABASE CACHING
文を明示的に実行して全データベース・キャッシュ強制モードを有効にできます。
自動的なデフォルト・モードとは逆に、強制完全データベース・キャッシュ・モードは、データベース・バッファ・キャッシュに適しているNOCACHE
LOBを含むデータベース全体を考慮します。このモードは、Oracle Database 12cリリース1 (12.1.0.2)以降で使用可能です。
注意:
全データベース・キャッシュ強制モードを有効にしても、データベースはメモリーに強制的に入れられません。正確に言えば、データベース全体がバッファ・キャッシュにキャッシュされる対象となります。Oracle Databaseは、アクセスされたときにのみ表をキャッシュします。
個々のインスタンスのバッファ・キャッシュ・サイズがデータベース・サイズよりも大きい場合にのみ、完全データベース・キャッシュ強制モードを有効化することをお薦めします。このガイドラインは、単一インスタンスとOracle RACデータベースの両方に適用されます。ただし、Oracle RACアプリケーションが適切にパーティション化されている場合、すべてのインスタンスのバッファ・キャッシュの合計にインスタンス間の重複キャッシュ・ブロックを処理する追加領域を加えたものがデータベース・サイズよりも大きい場合は、完全データベース・キャッシュ強制モードを有効化できます。
関連項目:
-
完全データベース・キャッシュ強制モードを有効にする方法の詳細は、Oracle Database管理者ガイドを参照してください
-
ALTER DATABASE ... FORCE FULL DATABASE CACHING
文の詳細は、Oracle Database SQL言語リファレンスを参照してください
DRAMおよびPMEMバッファ
標準の(DRAM)データベース・バッファは、PMEMバッファとは異なりますが、特性を共有しています。
Oracle永続メモリー・ファイルストア(PMEMファイルストア)を構成すると、すべてのデータ・ブロックがDRAMでバッファ・キャッシュに直接マップされます。DRAMバッファとは異なり、PMEMバッファではデータ・ブロックの内容はコピーされません。そうではなく、PMEMバッファ・ヘッダーはPMEMファイルストアに格納されているデータ・ブロックを指します。ほとんどの読取りでは、データベースはコンテンツではなくブロック・メタデータのみをキャッシュします。PMEMバッファでは、構造が標準バッファのキャッシュ・グラニュルとは異なる特殊なグラニュルの型が使用されます。
注意:
初期化パラメータDB_CACHE_SIZE
では、DRAMキャッシュの最小サイズを指定します。PMEMメタデータ・オーバーヘッドは、この割当てには含まれません。
PMEMバッファは、次のいずれかの状態になります。
-
現行
これはPMEMバッファの現在のバージョンです。ファイルストアから直接アクセスできます。
Oracle Databaseは、PMEMの現行バージョンを標準のDRAMバッファの現行バージョンから切り離して維持します。この分離によって、PMEMブロックのピンニング、クリーン・アップ、およびDRAMへの移行時のコードの複雑さを軽減できます。
-
一貫性
これは、PMEMバッファの読取り一貫性バージョンです。これは、データベースがDRAMにクローンを作成した後に作成されます。PMEMバッファには、ファイルストアから直接アクセスできます。
-
空き
これは、空きPMEMバッファです。PMEMブロックで再利用できます。インスタンスの起動後、すべてのPMEMバッファは空き状態になります。
PMEMのレイテンシはDRAMより長くなっています。Oracle Databaseでは、内部のワークロード・ベースのアルゴリズムを使用して、PMEMからDRAMに移行するブロックを決定します。
関連項目:
-
PMEMファイルストアの作成方法の詳細は、Oracle Database管理者ガイドを参照してください
REDOログ・バッファ
REDOログ・バッファとは、SGA内の循環バッファであり、データベースに加えられた変更についてのREDOエントリが格納されます。
REDOレコードは、DML操作やDDL操作によって行われた変更を再構築または再実行するために必要な情報が含まれているデータ構造です。データベースのリカバリでは、データファイルにREDOエントリを適用して、失われた変更が再構築されます。
REDOエントリは、データベース・プロセスによってユーザーのメモリー領域からSGA内のREDOログ・バッファにコピーされます。REDOエントリは、バッファ内で連続した領域を占めます。REDOログ・バッファは、バックグラウンド・プロセスのログ・ライター・プロセス(LGWR)によって、ディスク上のアクティブなオンラインREDOログ・グループに書き込まれます。図16-8に、このREDOバッファのアクティビティを示します。
DBWではデータ・ブロックは分散してディスクに書き込まれますが、LGWRではREDOログ・バッファはディスクに対して順次書き込まれます。通常、分散書込みの速度は順次書込みよりも大幅に遅くなります。LGWRでは、ユーザーはDBWによる遅い書込みが完了するまで待機する必要がないため、パフォーマンスが向上します。
LOG_BUFFER
初期化パラメータでは、Oracle DatabaseでREDOエントリをバッファリングする場合に使用するメモリー量を指定します。他のSGAコンポーネントとは異なり、REDOログ・バッファおよび固定SGAバッファのメモリーは、グラニュルに分割されません。
関連項目:
-
オンラインREDOログの詳細は、Oracle Database管理者ガイドを参照してください
共有プール
共有プールには、様々なタイプのプログラム・データがキャッシュされます。
たとえば、共有プールには、解析済のSQLやPL/SQLのコード、システム・パラメータ、データ・ディクショナリ情報などが格納されます。共有プールは、データベースで行われるほぼすべての操作に関連します。たとえば、ユーザーがSQL文を実行する場合にも、Oracle Databaseは共有プールにアクセスします。
共有プールは、複数のサブコンポーネントから構成されています。図16-9に、最も重要なサブコンポーネントを示します。
この項には次のトピックが含まれます:
ライブラリ・キャッシュ
ライブラリ・キャッシュとは、実行可能なSQLコードやPL/SQLコードが格納されている共有プール・メモリー構造です。
このキャッシュには、SQLとPL/SQLの共有領域や、ロックやライブラリ・キャッシュ・ハンドルなどの制御構造が含まれています。共有サーバー・アーキテクチャでは、ライブラリ・キャッシュにはプライベートSQL領域も含まれています。
SQL文が実行されると、データベースでは、以前に実行されたコードの再利用が試みられます。ライブラリ・キャッシュ内にSQL文の解析済表現が存在し、共有可能である場合には、そのコードが再利用され、これはソフト解析またはライブラリ・キャッシュ・ヒットと呼ばれます。それ以外の場合には、データベースでアプリケーション・コードの実行可能バージョンを新しく構築する必要があり、これはハード解析またはライブラリ・キャッシュ・ミスと呼ばれます。
共有SQL領域
データベースでは、実行される各SQL文の表現が共有SQL領域とプライベートSQL領域に保持されます。
SQL文が最初に実行されたときは、共有SQL領域を使用してSQL文が処理されます。この領域にはすべてのユーザーがアクセス可能であり、文の解析ツリーと実行計画が含まれています。一意の文に対して、共有SQL領域は1つのみ存在します。SQL文を発行するセッションは、それぞれのPGAにプライベートSQL領域を持っています。同じ文を発行する各ユーザーのプライベートSQL領域は、同じ共有SQL領域を指しています。これにより、異なるPGA内の数多くのプライベートSQL領域を同一の共有SQL領域に関連付けることができます。
データベースでは、アプリケーションによって同じSQL文が発行されたことが自動的に判断されます。ユーザーやアプリケーションが直接発行したSQL文も、他の文によって内部的に発行された再帰的SQL文も対象となります。
データベースでは、次のステップが実行されます。
-
構文およびセマンティクスが同一の文について共有SQL領域が存在しているかどうかを確認するため、共有プールがチェックされます。
-
同一の文が存在する場合、これ以降この文の新たなインスタンスが実行されるときには共有SQL領域が使用されるため、メモリー消費が削減されます。
-
同一の文が存在しない場合は、共有プールに新しい共有SQL領域が割り当てられます。構文が同じであるもののセマンティクスが異なる文の場合は、子カーソルが使用されます。
どちらの場合も、ユーザーのプライベートSQL領域が、その文と実行計画を含む共有SQL領域に対応付けられます。
-
-
セッションのためにプライベートSQL領域が割り当てられます。
プライベートSQL領域の位置は、セッションのために確立される接続に応じて異なります。セッションが共有サーバーを介して接続されている場合、プライベートSQL領域の一部はSGA内に保持されます。
図16-10に、専用サーバー・アーキテクチャにおいて、2つのセッションが同じSQL文のコピーをそれぞれのPGA内に保持する様子を示します。共有サーバーでは、このコピーはラージ・プール内のUGAにあり、ラージ・プールが存在しない場合は、共有プール内のUGAにあります。
関連項目:
-
ライブラリ・キャッシュの管理の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
-
共有SQLの詳細は、Oracle Database開発ガイドを参照してください
プログラム・ユニットとライブラリ・キャッシュ
ライブラリ・キャッシュには、PL/SQLプログラムおよびJavaクラスの実行可能形式が保持されます。これらは、プログラム・ユニットと総称されます。
データベースでは、プログラム・ユニットはSQL文と同様に処理されます。たとえば、データベースでは、割り当てられた共有領域にPL/SQLプログラムの解析済かつコンパイル済の形式が保持されます。データベースでは、ローカル変数、グローバル変数、パッケージ変数、SQL実行用バッファなど、プログラムを実行するセッションに固有の値を保持するためのプライベート領域が割り当てられます。複数のユーザーが同じプログラムを実行する場合は、各ユーザーが独自のプライベートSQL領域を持ち、セッション固有の値はそこに保持され、単一の共有SQL領域にアクセスします。
データベースでは、PL/SQLプログラム・ユニット内の個別のSQL文はすでに説明したように処理されます。PL/SQLプログラム・ユニット内の起点には関係なく、これらのSQL文は解析された表現を保持するために共有領域を使用し、その文を実行するセッションごとにプライベートSQL領域を使用します。
共有プール内のメモリーの割当てと再利用
データベースでは、新しいSQL文が解析されたときに共有プール・メモリーが割り当てられますが、共有可能と想定されないDDLの文である場合は例外です。割り当てられるメモリーのサイズは、文の複雑度に応じて決められます。
一般的に共有プール内の項目は、最低使用頻度(LRU)アルゴリズムに従ってデータベースが削除するまで残されたままです。多数のセッションが使用している共有プール項目は、その項目を作成したデータベース・プロセスが終了しても、その項目が使用されているかぎりメモリーに残ります。このメカニズムによって、SQL文のオーバーヘッドと処理を最小限に抑えることができます。新しい項目の領域が必要になった場合は、頻繁に使用されていない項目で使用されるメモリーが解放されます。
ALTER SYSTEM FLUSH SHARED_POOL
文では共有プール内のすべての情報が削除され、同様にグローバル・データベース名も変更されます。
関連項目:
-
共有SQL領域のライフサイクルの概要は、『Oracle Database SQLチューニング・ガイド』を参照
-
ALTER SYSTEM FLUSH SHARED_POOL
の使用方法の詳細は、『Oracle Database SQL言語リファレンス』を参照 -
V$SQL
およびV$SQLAREA
動的ビューの詳細は、『Oracle Databaseリファレンス』を参照
データ・ディクショナリ・キャッシュ
データ・ディクショナリとは、データベース、データベースの構造およびそのユーザーについての参照情報を含むデータベース表およびビューの集合です。
Oracle Databaseは、SQL文の解析時にデータ・ディクショナリに頻繁にアクセスします。データ・ディクショナリはOracle Databaseによって頻繁にアクセスされるので、ディクショナリ・データを保持するために、次のような特別な場所がメモリー内に指定されています。
-
データ・ディクショナリ・キャッシュ
このキャッシュには、データベース・オブジェクトについての情報が保持されています。データがバッファではなく行として保持されるため、このキャッシュは行キャッシュとも呼ばれます。
-
ライブラリ・キャッシュ
これらのキャッシュは、データ・ディクショナリ情報にアクセスするすべてのサーバー・プロセスによって共有されます。
関連項目:
-
データ・ディクショナリ・キャッシュに追加のメモリーを割り当てる方法の詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
サーバー結果キャッシュ
サーバーの結果キャッシュは共有プール内のメモリー・プールです。バッファ・プールとは異なり、サーバー結果キャッシュにはデータ・ブロックではなく結果セットが保持されています。
注意:
クライアント結果キャッシュは、サーバー結果キャッシュとは異なります。クライアント・キャッシュはアプリケーション・レベルで構成されており、データベース・メモリーではなくクライアント・メモリー内に配置されます。
SQL問合せ結果キャッシュ
SQL問合せ結果キャッシュは問合せおよび問合せの断片の結果を格納するサーバー結果キャッシュのサブセットです。結果キャッシュは、データベース・レベルまたは文レベルで有効化または無効化できます。
問合せを実行すると、データベースはその結果が問合せ結果キャッシュに存在するかどうかを判断します。結果がキャッシュされておらず、キャッシュが問合せで有効になっている場合、データベースは問合せを実行して結果を返し、キャッシュします。ただし、結果が存在する場合、問合せを実行せずにキャッシュから取得します。
結果を構成するために使用されているデータベース・オブジェクトのデータまたはメタデータがトランザクションで変更されると、キャッシュされた結果はデータベースにより自動的に無効化されます。次の問合せはキャッシュされた結果を使用できないため、データベースは新しい結果を自動的に計算し、以降の問合せで使用するためにキャッシュします。このキャッシュ・リフレッシュ・プロセスは、アプリケーションに対して透過的です。
実際には、問合せ結果キャッシュは、データベースで必要に応じて作成および保持されるジャストインタイムのマテリアライズド・ビューとして機能します。キャッシュを使用すると、データ・ブロックの再読取りおよび結果の再計算というコストのかかる操作を回避できます。ほとんどのアプリケーションにとって、このキャッシュによるパフォーマンス向上は有益です。
関連項目:
問合せ結果キャッシュを使用して応答時間を最適化する方法は、Oracle Database管理者ガイドを参照してください
PL/SQLファンクション結果キャッシュ
PL/SQLファンクション結果キャッシュはファンクションの結果セットを格納するサーバー結果キャッシュのサブセットです。
キャッシュがない場合には、1コール当たり1秒かかるPL/SQLファンクションを1000回コールすると、1000秒かかります。キャッシュがある場合は、このファンクションを同じ入力を使用して1000回コールしても全体で1秒しかかかりません。結果キャッシュは、比較的静的なデータに依存し、頻繁に起動されるファンクションに適しています。
PL/SQLファンクション・コードには、その結果をキャッシュするように要求するコードを含めることができます。このようなファンクションが起動されると、システムによってキャッシュがチェックされます。同じパラメータ値が指定された以前のファンクション・コールの結果がキャッシュに含まれている場合は、実行者に結果が戻され、ファンクション本体は再実行されません。キャッシュに結果が含まれていない場合は、ファンクション本体が実行され、実行元に制御が戻される前に、指定されたパラメータ値での結果がキャッシュに追加されます。
注意:
キャッシュされた結果を計算するために使用されるデータベース・オブジェクトを指定して、これらのオブジェクトのいずれかが更新された場合にキャッシュされた結果が無効になり、再計算されるように設定できます。
異なる引数で頻繁に起動される関数では、再利用頻度が低い結果が生成され、パフォーマンスが低下につながります。Oracle Databaseは、RESULT_CACHE
ヒントがある最近使用されたPL/SQLファンクションを追跡します。この履歴を使用して、データベースはPL/SQLファンクションと引数のペアを最近の履歴でx回検出した場合にのみキャッシュします。xは内部のしきい値によって設定されます。キャッシュされている結果が多すぎるためにデータベースがさらにメモリーを必要とする場合は、キャッシュされた結果が1つ以上エージ・アウトされます。
RESULT_CACHE_EXECUTION_THRESHOLD
は、ファンクションと特定の引数セットがキャッシュされるまでに表示する必要がある回数を指定します。持っている引数が異なるファンクション(たとえば、MYFUNC(1,2)
とMYFUNC(1,3)
)は一意とみなされることに注意してください。このパラメータは、セッション・レベルではなくシステム・レベルでのみ設定できます。
関連項目:
-
PL/SQLファンクション結果キャッシュの詳細は、『Oracle Database開発ガイド』を参照してください
-
PL/SQLファンクション結果キャッシュの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください
サーバー結果キャッシュのインフラストラクチャ
問合せ結果キャッシュとPL/SQLファンクション結果キャッシュは、同じインフラストラクチャを共有します。
オブジェクト・タイプ: 結果、依存性、一時
サーバー結果キャッシュ内で、結果オブジェクトは、問合せまたはPL/SQLファンクションによって戻される行を格納するデータ構造です。依存性オブジェクトには、結果オブジェクトとして格納された問合せによって参照されるオブジェクトのメタデータが格納されます。
典型的な問合せ結果は、小規模で、計算にコストがかかり、再使用頻度が高く、不揮発性の表に基づいています。ただし、結果が大きくなる場合があります。問合せ結果が制限を超えた場合、結果の一部は一時メモリー内の一時オブジェクトとして格納され、別の一部は標準結果オブジェクトとして格納されます。一時オブジェクトは、実際の問合せ結果を保持する一時表領域セグメントを指す結果キャッシュ・メタデータのコレクションです。
結果サブキャッシュ
ワークロードによっては、読取り/書込みアクセス時により高い同時実行性をサポートするために、データベースが結果サブキャッシュを作成する場合があります。Oracle Databaseでは内部アルゴリズムを使用して、サブキャッシュを作成するかどうか、作成する場合はその数を決定します。
サーバー結果キャッシュのユーザー・インタフェース
RESULT_CACHE_MODE
初期化パラメータは、SQL問合せ結果キャッシュがすべての可能な問合せで使用されるか、ヒントが設定された問合せにのみ使用されるかを決定します。
RESULT_CACHE_MAX_TEMP_SIZE
初期化パラメータは、PDBで結果キャッシュが使用できる一時表領域メモリーの最大量を制御します。RESULT_CACHE_MAX_TEMP_RESULT
は、キャッシュした1つの問合せで使用できる、一時表領域メモリーの最大量を制御します。
RESULT_CACHE_MODE
パラメータの設定をオーバーライドするには、問合せまたは問合せのフラグメントにRESULT_CACHE
のヒントを使用して注釈を付けることができます。Oracle Database 20cから、ヒントでTEMP={TRUE|FALSE}
オプションが受け入れられ、結果を一時表領域に格納できるかどうかが制御されます。
DBMS_RESULT_CACHE
パッケージを使用すると、SQL結果キャッシュとPL/SQLファンクション結果キャッシュで使用される共有プールの部分を管理できます。オブジェクトを無効化し、問合せおよびオブジェクトをブラックリストに登録し、関連操作を実行できます。
V$RESULT_CACHE_OBJECTS.TYPE
列は、キャッシュ内のオブジェクトのタイプを示します。問合せ結果が一時表領域に格納されている場合、TYPE
によってResult
とTemp
の2つのオブジェクトが表示されます。サブキャッシュ・メタデータには、V$RESULT_SUBCACHE_STATISTICS
および関連ビューを使用してアクセスできます。
関連項目:
-
結果キャッシュの動作のサイズ設定および制御の詳細は、Oracle Database管理者ガイドを参照してください
-
DBMS_RESULT_CACHE
パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください -
クライアント結果キャッシュの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください
-
RESULT_CACHE_MODE
初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください -
RESULT_CACHE
ヒントの詳細は、『Oracle Database SQL言語リファレンス』を参照してください
予約プール
予約プールは共有プール内のメモリー領域であり、Oracle Databaseで大量の連続したメモリーのチャンクを割り当てる場合に使用できます。
データベースによって、共有プールからメモリーがチャンクで割り当てられます。チャンクを使用することによって、単一の連続した領域がない場合でもキャッシュに大きなオブジェクト(5KBよりも大きいオブジェクト)をロードできます。これにより、データベースでは、断片化によって連続したメモリーが使用できなくなる可能性が低減されます。
まれに、Java、PL/SQLまたはSQLカーソルによって、5KBを超える領域が共有プールから割り当てられることがあります。このような割当てが最も効率的に行われるように、データベースでは共有プールの一部分が予約プールとして分離されています。
関連項目:
予約プールの構成方法の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください
ラージ・プール
ラージ・プールは、共有プールでの割当てには適さない大量のメモリー割当て用のオプションのメモリー領域です。
ラージ・プールでは、次のような領域に対して大量のメモリー割当てを行うことができます。
-
共有サーバーおよびOracle XAインタフェース用のUGA(トランザクションが複数のデータベースと対話する環境で使用)
-
パラレル実行で使用されるメッセージ・バッファ
-
Recovery Manager(RMAN)I/Oスレーブ用のバッファ
-
遅延挿入のバッファ(
MEMOPTIMIZE_WRITE
ヒントによる挿入)
次の図は、ラージ・プールを示しています。
関連項目:
-
パラレル実行用にメモリーを割り当てる方法は、「問合せコーディネータ」を参照してください
-
共有サーバーのセッション・メモリーの割当ての詳細は、「ディスパッチャのリクエスト・キューとレスポンス・キュー」を参照してください
-
Oracle XAの詳細は、『Oracle Database開発ガイド』を参照してください。
-
ラージ・プールの詳細は、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
ラージ・プール・メモリー管理
ラージ・プールのメモリーの管理方法は共有プールとは異なります。共有プールの場合は、メモリーの一部をエージ・アウトできるようにLRUリストが使用されます。
ラージ・プールには、LRUリストはありません。データベース・セッションにラージ・プール・メモリーが割り当てられると、このメモリーは、セッションで解放されるまで、解放できません。メモリーの一部が解放されると、その領域は他のプロセスがすぐに使用できます。セッション・メモリーをラージ・プールから割り当てることにより、共有プールで発生する可能性のある断片化を防ぎます。
遅延挿入のためのラージ・プール・バッファ
遅延挿入と呼ばれる特殊なタイプの挿入の場合、データベースはバッファをラージ・プールから割り当てます。
Internet of Things (IoT)アプリケーションからのファイア・アンド・フォーゲット方式の高速な挿入においては、データベース・インフラストラクチャにおいてパフォーマンス・オーバーヘッドが発生します。たとえば、コード・パスには、バッファ・キャッシュ・ナビゲーション、バッファ・ピンおよび同時実行性保護が含まれます。配列の挿入によってこれらのコストは最小限に抑えられるものの、配列はクライアント側で構築される必要があり、これは、Internet of Thingsアプリケーションにおいては一般的ではありません。この問題に対処するために、Oracleアプリケーションではヒントを使用して、MEMOPTIMIZE FOR WRITE
として指定された表に行を挿入できます。
この挿入はラージ・プールにバッファされ、バックグラウンド・プロセスによって後から非同期にディスクに書き込まれるため、遅延されます。データベースでは遅延挿入は次のように処理されます。
-
アプリケーションは
MEMOPTIMIZE_WRITE
挿入を、データを集計できる中間層に送ります。ほとんどの場合、IoTアプリケーションは挿入を中間層に送信しますが、データベースに挿入を直接送信することもできます。たとえば、SQL*Plusを使用すると挿入がデータベースに直接送信されます。 -
中間層は、挿入の集計をデータベース・サーバーに書き込みます。
-
オプションで、中間層クライアントは、前のステップで書き込んだデータのローカル・コピーを保持します。
-
サーバー・プロセスは、ラージ・プールのバッファにデータを書き込みます。
競合を防ぐために、各バッファには独自の内部ロック・メカニズムがあります。このロック・メカニズムは、データベース・バッファ・キャッシュがバッファに対して使用するロック・メカニズムとは異なります。基本的な書込みプロセスは次のとおりです。
-
インスタンスの起動後、最初の
MEMOPTIMIZE_WRITE
挿入によって、ラージ・プールからバッファが割り当てられます。 -
ライターは、使用可能なバッファのリストからバッファを選択します。
-
選択したバッファがロックされておらず、かつそのバッファに空き領域がある場合、クライアントはそのバッファへの書込みを行い、セッション固有の順序番号が各バッファ書込みにスタンプされます。そうでない場合、ライターは前のステップに戻り、バッファが見つかるか、ラージ・プールで十分な領域が解放されるまでこの方法を続行します。
-
-
データベースで、バッファされたデータからサーバー側配列が作成されます。
-
Space Management Coordinator (SMCO)とそのヘルパー・プロセス(Wnnn)は、標準のデータ・ブロックの形式を使用して配列をディスクに非同期に書き込みます。
標準挿入とは異なり、遅延挿入は自動的にコミットされ、ロールバックできません。データベースは、指定されたオブジェクトへの挿入をセッションに出現する順序でコミットします。オブジェクトまたはセッションどうしの順序付けは保証されません。
データベースでは、通常の挿入と同様に制約および索引のメンテナンスがサポートされます。ただし、データベースは、ラージ・プールへの書込み時ではなくディスクへの書込み時に評価を実行します。
注意:
最適なパフォーマンスを得るには、制約を無効にすることをお薦めします。
次の図は、遅延挿入のワークフローを示しています。
関連項目:
-
表を
MEMOPTIMIZE FOR WRITE
として指定する方法の詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください -
INSERT
の構文およびセマンティクスについては、Oracle Database SQL言語リファレンスを参照してください -
MEMOPTIMIZE_POOL_SIZE
の詳細は、Oracle Databaseリファレンスを参照してください。
Javaプール
Javaプールは、Java仮想マシン(JVM)内のセッション固有のすべてのJavaコードとデータが格納されるメモリー領域です。このメモリーには、コール終了時にJavaセッション領域に移行されるJavaオブジェクトが含まれています。
専用サーバー接続では、Javaプールには各Javaクラスの共有部分(メソッドおよびコード配列などの読取り専用メモリー)が含まれていますが、各セッションのセッションごとのJava状態は含まれていません。共有サーバーでは、プールには、各クラスの共有部分および各セッションの状態に使用される一部のUGAが含まれています。各UGAは必要に応じて拡大および縮小されますが、UGAの合計サイズはJavaプール領域に収まる必要があります。
Java Pool Advisor統計は、Javaに使用されるライブラリ・キャッシュ・メモリーに関する情報を提供し、Javaプールのサイズの変化が解析率に及ぼす影響を予測します。Java Pool Advisorは、statistics_level
をTYPICAL
以上に設定すると内部的にオンに設定されます。これらの統計は、アドバイザをオフにするとリセットされます。
関連項目:
-
Javaプール・アドバイザ統計を含むビューの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください
固定SGA
固定SGAは、内部のハウスキーピング用領域です。
固定SGAには、たとえば次のような情報が含まれています。
-
バックグラウンド・プロセスがアクセスする必要のある、データベースとインスタンスの状態に関する一般的な情報
-
ロックに関する情報など、プロセス間で通信される情報
固定SGAのサイズはOracle Databaseによって設定され、手動では変更できません。固定SGAのサイズは、リリースによって異なります。
関連項目:
オプションのパフォーマンス関連SGAサブ領域
インメモリー領域
インメモリー領域は、インメモリー列ストア(IM列ストア)が含まれるオプションのSGAコンポーネントです。
IM列ストアには、迅速にスキャンできるように最適化された列形式で表のコピー、パーティションおよびマテリアライズド・ビューが格納されています。IM列ストアは、従来の行形式でデータを格納するデータベースバッファ・キャッシュを補完するものです。
注意:
IM列ストアを有効にするには、Oracle Databaseインメモリー・オプションが必要です。
関連項目:
インメモリー領域およびIM列ストアの詳細は、Oracle Database In-Memoryガイドを参照してください
Memoptimizeプール
memoptimizeプールには、バッファおよびMEMOPTIMIZE FOR READ
と指定されたヒープ構成表の関連構造が格納されます。
この構造は、SELECT * FROM cust WHERE cid = 10
などのキー・ベースの問合せに対して優れたパフォーマンスとスケーラビリティを提供します。エンドツーエンドのレスポンス時間を短縮するために、クライアントはリクエストしたバッファをネットワーク経由でSGAから直接プルし、CPUとオペレーティング・システムのオーバーヘッドを回避します。アプリケーションは、コードを変更することなくmemoptimizeプールを利用できます。
memoptimizeプールは次の2つのパートで構成されています。
-
Memoptimizeバッファ領域
ディスクI/Oを回避するために、データベースはmemoptimizeプールで
MEMOPTIMIZE FOR READ
表のバッファを、表にNO MEMOPTIMIZE FOR READ
のマークが付くまで永続的にロックします。memoptimizeバッファには、データベース・バッファ・キャッシュ内のバッファと同じ構造が使用されます。ただし、memoptimizeプールのバッファは、データベース・バッファ・キャッシュから完全に分離され、そのサイズにカウントされません。memoptimizeバッファ領域はmemoptimizeプールの75%を占めます。 -
ハッシュ索引
ハッシュ索引は、非永続なセグメント・データ構造です。データベースは、複数の非連続メモリー単位としてハッシュ索引を割り当てます。各単位には、複数のハッシュ・バケットが含まれます。個別のマップ構造により、メモリー単位と主キーが関連付けられます。ハッシュ索引はmemoptimizeプールの25%を占めます。
memoptimizeプールを有効にするには、MEMOPTIMIZE_POOL_SIZE
初期化パラメータを整数値に設定します(プールはデフォルトで無効になっています)。この値は、プールに割り当てるSGAの量を指定します。MEMOPTIMIZE_POOL_SIZE
値はSGA_TARGET
の対象ですが、データベースはmemoptimizeプールを自動では拡大および縮小しません。たとえば、SGA_TARGET
が10 GBで、 MEMOPTIMIZE_POOL_SIZE
が1 GBの場合、使用可能なSGAメモリーはmemoptimizeプール以外の合計9 GBです。
memoptimizeプールのサイズを変更するには、MEMOPTIMIZE_POOL_SIZE
を手動で設定し、データベース・インスタンスを再起動する必要があります。ALTER SYSTEM
を使用して動的にプール・サイズを変更することはできません。
DBMS_MEMOPTIMIZE
パッケージを使用すると、memoptimizeプールに表を明示的に追加できます。
関連項目:
-
データベース・メモリー管理の概要は、Oracle Database 2日でデータベース管理者を参照してください
-
memoptimizeプールを有効にして問合せのパフォーマンスを向上させる方法については、Oracle Databaseパフォーマンス・チューニング・ガイドを参照してください
-
DBMS_MEMOPTIMIZE
パッケージの詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください -
CREATE TABLE ... MEMOPTIMIZE FOR READ
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
MEMOPTIMIZE_POOL_SIZE
の詳細は、Oracle Databaseリファレンスを参照してください。
ソフトウェア・コード領域の概要
ソフトウェア・コード領域は、実行中または実行できるコードを保管するメモリーの部分です。Oracle Databaseのコードはソフトウェア領域に格納され、通常、この場所はユーザー・プログラムの格納場所よりも排他的であり、保護されています。
ソフトウェア領域のサイズは通常固定されており、ソフトウェアの更新時か再インストール時にかぎり変化します。これらの領域に必要なサイズは、オペレーティング・システムによって異なります。
ソフトウェア領域は読取り専用で、共有または非共有でインストールされます。Oracle FormsやSQL*Plusなど一部のデータベース・ツールおよびユーティリティは共有でインストールできますが、共有でインストールできないものもあります。データベースのコードは、メモリー内に複数のコピーを格納することなくすべてのユーザーがアクセスできるよう、可能なかぎり共有され、これにより、メイン・メモリーの使用量が削減されて、全体的にパフォーマンスが向上します。データベースの複数のインスタンスが同じコンピュータ上で実行されている場合、それらのインスタンスは異なるデータベースにおいても同じデータベース・コード領域を使用できます。
注意:
ソフトウェアを共有でインストールするオプションは、すべてのオペレーティング・システムで使用できるわけではありません(たとえば、Microsoft Windowsが稼働しているPCでは使用できません)。詳細は、オペレーティング・システム別のドキュメントを参照してください。