日本語PDF

14 共有プールおよびラージ・プールのチューニング

この章では、共有プールおよびラージ・プールのチューニング方法を説明します。自動メモリー管理を使用してシステムのデータベース・メモリーを管理している場合、または自動共有メモリー管理を使用して共有グローバル領域(SGA)を構成している場合は、この章で説明されているように、共有プールおよびラージ・プールを手動でチューニングする必要はありません。

この章のトピックは、次のとおりです:

共有プールについて

異なるタイプのデータをキャッシュするには、共有プールを使用します。キャッシュされたデータには、PL/SQLブロックおよびSQL文のテキストおよび実行可能フォーム、ディクショナリ・キャッシュ・データ、結果キャッシュ・データおよびその他のデータが含まれています。

この項では、共有プールについて説明しており、内容は次のとおりです。

共有プールを使用する利点

共有プールを適切な大きさにして使用すると、次の4つの方法でリソース使用量を低減できます。

  • SQL文が共有プールにある場合は、解析のオーバーヘッドを回避できるため、システムのCPUリソースやエンド・ユーザーの経過時間が低減します。

  • リソース使用のラッチングが大幅に減少して、スケーラビリティがさらに増大します。

  • すべてのアプリケーションがSQL文およびディクショナリ・リソースの同一プールを使用するので、共有プール・メモリーの必要量が低減されます。

  • 共有プールのディクショナリ要素はディスク・アクセスが不要なので、I/Oが減少します。

共有プールの概念

共有プールの主なコンポーネントは、次のとおりです。

  • ライブラリ・キャッシュ

    ライブラリ・キャッシュは、最近参照されたSQLとPL/SQLコードの実行可能な(解析またはコンパイルされた)形式を格納します。

  • データ・ディクショナリ・キャッシュ

    データ・ディクショナリ・キャッシュは、データ・ディクショナリから参照されたデータを格納します。

  • サーバー結果キャッシュ(構成により異なります)

    サーバーの結果キャッシュは、問合せの結果とPL/SQLファンクションの結果を格納する共有プール内のオプションのキャッシュです。サーバー結果キャッシュの詳細は、「結果キャッシュについて」を参照してください。

ライブラリ・キャッシュやディクショナリ・キャッシュなどの共有プール内のキャッシュの多くは、必要に応じてサイズを自動的に増減します。共有プールに空き領域がない場合は、新しいエントリを受け入れるために古いエントリが除去されます。

ライブラリ・キャッシュやデータ・ディクショナリ・キャッシュでのキャッシュ・ミスは、バッファ・キャッシュでのミスよりも影響が大きくなります。このため、共有プールには、頻繁に使用されるデータが確実にキャッシュされるように、サイズを設定する必要があります。

共有サーバー、パラレル問合せ、Recovery Managerなど、共有プールに大量のメモリーを割り当てる必要がある機能は複数あります。これらの機能によって使用されるシステム・グローバル領域(SGA)メモリーを分離するために、個別のメモリー領域(ラージ・プール)を使用することをお薦めします。

共有プールからのメモリーの割当ては、チャンクで行われます。このチャンクによって、1つの連続領域を必要とせずにラージ・オブジェクト(5KBより多い)をキャッシュにロードできます。この方法では、フラグメント化のために連続メモリーが不足する可能性が少なくなります。

Java、PL/SQLまたはSQLカーソルによって、5KBを超える領域が共有プールから割り当てられることがあります。このような割当てをより効率よく行うために、Oracle Databaseでは、少量の共有プールを分離します。共有プールの領域が不足すると、予約プールと呼ばれる分離されたメモリーが使用されます。

次の各項では、共有プールの主なコンポーネントの詳細を説明します。

ライブラリ・キャッシュの概念

ライブラリ・キャッシュには、総称してアプリケーション・コードと呼ばれる、実行可能な形式のSQLカーソル、PL/SQLプログラムおよびJavaクラスが格納されます。アプリケーション・コードに関連するため、この項ではチューニングを中心に説明します。

アプリケーション・コードが実行されると、既存のコードが以前に実行されており、共有できる場合は、Oracle Databaseによりそのコードの再利用が試行されます。解析されたSQL文の表現がライブラリ・キャッシュ内に存在し、共有できる場合は、既存のコードが再利用されます。これは、ソフト解析またはライブラリ・キャッシュ・ヒットと呼ばれています。既存のコードを使用できない場合は、アプリケーション・コードの新しい実行可能バージョンを作成する必要があります。これは、ハード解析またはライブラリ・キャッシュ・ミスと呼ばれています。SQL文およびPL/SQL文を共有できる場合の詳細は、「SQL共有基準」を参照してください。

ハード解析を実行するには、ソフト解析の実行時より多くのリソースを使用します。ソフト解析に使用するリソースには、CPUおよびライブラリ・キャッシュ・ラッチ取得が含まれます。ハード解析に必要なリソースには、追加のCPU、ライブラリ・キャッシュ・ラッチ取得および共有プール・ラッチ取得が含まれます。ハード解析は、SQL文を処理するときの解析ステップまたは実行ステップのいずれかで発生します。

アプリケーションがSQL文の解析コールを行うとき、解析された文の表現がライブラリ・キャッシュにまだ存在しない場合、Oracle Databaseはその文を解析し、共有プールに解析されたフォームを格納します。解析コールのライブラリ・キャッシュ・ミスを低減するため、可能な場合には、すべての共有可能なSQL文が共有プールに格納されていることを確認してください。

アプリケーションでSQL文の実行コールを行ったときに、SQL文の実行可能部分が、別の文の領域を確保するためにライブラリ・キャッシュから除去(または割当て解除)されていた場合、Oracle Databaseはその文を暗黙的に再解析し、新しい共有SQL領域を作成してその文を実行します。この場合も、ハード解析が発生します。実行コールでのライブラリ・キャッシュ・ミスを低減するには、ライブラリ・キャッシュに割り当てるメモリーを増やします。

ハード解析およびソフト解析の詳細は、「SQLの実行効率」を参照してください。

データ・ディクショナリ・キャッシュの概念

データ・ディクショナリ・キャッシュに格納される情報は、次のとおりです。

  • ユーザー名

  • セグメント情報

  • プロファイル・データ

  • 表領域情報

  • 順序番号

また、データ・ディクショナリ・キャッシュはスキーマ・オブジェクトを説明する情報、すなわちメタデータも格納します。メタデータが使用されるのは、SQLカーソルの解析時かPL/SQLプログラムのコンパイル時です。

SQL共有基準

Oracle Databaseでは、SQL文またはPL/SQLブロックを発行する際に、共有プールに同じ文が存在するかどうかを自動的に確認します。

SQL文のテキストと、共有プール内の既存のSQL文を比較するために、Oracle Databaseでは次のステップが実行されます。

  1. SQL文のテキストがハッシュされます。

    一致するハッシュ値がない場合、SQL文は共有プール内に現在存在せず、ハード解析が実行されます。

  2. 共有プール内の既存のSQL文に一致するハッシュ値がある場合は、一致した文のテキストが、ハッシュされた文のテキストと比較され、それらが同一であるかどうかが確認されます。

    SQL文やPL/SQLブロックのテキストは、空白、大文字小文字の区別、コメントも含め、完全に同一である必要があります。たとえば、次の文は同じ共有SQL領域を使用できません。

    SELECT * FROM employees;
    SELECT * FROM Employees;
    SELECT *  FROM employees;
    

    また、リテラルのみ異なるSQL文は同じ共有SQL領域を使用できません。たとえば、次の文は同じSQL領域に変換されません。

    SELECT count(1) FROM employees WHERE manager_id = 121;
    SELECT count(1) FROM employees WHERE manager_id = 247;
    

    このルールの唯一の例外は、CURSOR_SHARINGパラメータがFORCEに設定されている場合で、類似の文でSQL領域を共有できます。カーソル共有に関わるデメリットとメリットの詳細は、「カーソルの共有」を参照してください。

  3. 発行された文で参照されたオブジェクトは、共有プール内のすべての既存の文の参照済オブジェクトと比較され、両方のオブジェクトが同一であるかどうかが確認されます。

    SQL文やPL/SQLブロック内でスキーマ・オブジェクトを参照する際には、同じスキーマ内の同じオブジェクトである必要があります。たとえば、2人のユーザーが次のSQL文を発行したが、各ユーザーに独自のemployees表がある場合、文はユーザーごとに異なる表を参照するので、この文は同一とみなされません。

    SELECT * FROM employees;
    
  4. SQL文の中のバインド変数は、名前、データ型および長さで一致している必要があります。

    たとえば、次の文で同じ共有SQL領域を使用できないのは、バインド変数名が異なるためです。

    SELECT * FROM employees WHERE department_id = :department_id;
    SELECT * FROM employees WHERE department_id = :dept_id;
    

    多くのOracle製品(Oracle Formsやプリコンパイラなど)は、文をデータベースに渡す前にSQLを変換します。首尾一貫したSQL文の集合が生成されるように、文字は大文字に統一して変換され、空白は圧縮され、バインド変数は改名されます。

  5. セッションの環境は同一である必要があります。

    たとえば、SQL文は、同一の最適化目標を使用して最適化する必要があります。

関連項目:

CURSOR_SHARING初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください

共有プールの使用

共有プールの重要な目的は、SQL文とPL/SQL文の実行可能バージョンをキャッシュすることです。これにより、ハード解析にリソースを使用することなく、同じSQLまたはPL/SQLコードを複数回実行できるので、CPU、メモリーおよびラッチの使用が大幅に減少します。

また、共有プールは、データ・ウェアハウス・アプリケーションで非共有SQLをサポートできます。これらのアプリケーションでは、同時実行性が低くリソース使用率の高いSQL文が実行されます。このような状況では、リテラル値を持つ非共有SQLを使用することをお薦めします。バインド変数ではなくリテラル値を使用すると、オプティマイザは優れた列選択性の見積りを行えるので、最適なデータ・アクセス・プランが提供されます。

広く普及しているオンライン・トランザクション処理(OLTP)システムでは、共有プールを効率的に使用すると、解析関連アプリケーションでスケーラビリティの問題が発生する確率を大幅に低減できます。OLTPシステムには、共有プールと関連リソースの効率的な使用を実現するいくつかの方法があります。

関連項目:

共有プールでパラレル問合せを実行した場合の影響の詳細は、Oracle Database VLDBおよびパーティショニング・ガイドを参照してください

共有カーソルの使用

同じアプリケーションを実行する複数のユーザーのために共有SQLを再利用すると、ハード解析が回避されます。ソフト解析は、共有プール・ラッチやライブラリ・キャッシュ・ラッチなどのリソース使用量を大幅に減少させます。

共有カーソルを使用するには:

  • 可能な場合、SQL文ではリテラルではなくバインド変数を使用します。

    たとえば、次の2つのSQL文は字面が完全には一致しないので、同じ共有領域は使用できません。

    SELECT employee_id FROM employees WHERE department_id = 10;
    SELECT employee_id FROM employees WHERE department_id = 20;
    

    リテラルをバインド変数と置換すると、2回実行可能なSQL文が1つのみ生成されます。

    SELECT employee_id FROM employees WHERE department_id = :dept_id;
    

    バインド変数を使用するためにコードをリライトすることが実際的ではない既存のアプリケーションについては、「カーソルの共有」で説明されているように、CURSOR_SHARING初期化パラメータを使用してハード解析のオーバーヘッドをある程度回避できます。

  • 多数のユーザーが動的な非共有のSQL文を発行するようなアプリケーションを設計しないようにしてください。

    通常、大半のユーザーが必要とするデータの大部分は、事前に設定されている問合せを使用して満たすことができます。そのような機能が必要な場合は、動的SQLを使用します。

  • アプリケーションのユーザーが最適化アプローチと目標を各セッションに対して変更しないことを確認してください。

  • アプリケーション開発者に対し、次のポリシーを設定します。

    • SQL文とPL/SQLブロックに対して、バインド変数のネーミング規則と、スペーシング規定を標準化します。

    • 可能な場合、ストアド・プロシージャを使用することを考慮してください。

      そうすれば、同じストアド・プロシージャを発行している複数のユーザーが、同じ共有PL/SQL領域を自動的に使用します。ストアド・プロシージャは解析済フォームに格納されるため、ストアド・プロシージャを使用するとランタイム解析が減少します。

  • 同一であっても共有されていないSQL文についてV$SQL_SHARED_CURSORビューを問い合せて、カーソルが共有されない理由を判断します。

    これには、オプティマイザの設定とバインド変数の不整合などがあります。

関連項目:

カーソル共有の詳細は、Oracle Database SQLチューニング・ガイドを参照してください

シングル・ユーザー・ログオンおよび修飾表の参照の使用

ユーザーがそれぞれ固有のユーザー・ログインを使用してデータベースにログインする大規模なOLTPシステムでは、パブリック・シノニムを使用するかわりにセグメント所有者を明示的に認定することで、ディクショナリ・キャッシュのエントリ数が大幅に少なくなります。

表名を認定する別の方法として、個々のユーザー・ログオンではなくシングル・ユーザー・ログオンでデータベースに接続します。ユーザー・レベルの検証は、中間層でローカルに行われます。

PL/SQLの使用

ストアドPL/SQLパッケージを使用すると、多数のユーザーが個々にユーザー・ログオンとパブリック・シノニムを持つシステムにおける、スケーラビリティの問題を克服できます。これは、パッケージがコール元ではなく所有者として実行されるため、ディクショナリ・キャッシュの負荷がかなり削減されるためです。

ノート:

スケーラビリティの問題を克服するために、定義者権限パッケージの使用をお薦めします。ディクショナリ・キャッシュの負荷軽減の利点は、実行者権限パッケージの場合ほど大きくはありません。

DDL操作の実行の回避

ピーク時間に使用率の高いセグメントでDDL操作を実行しないようにします。これらのセグメントでDDL操作を実行すると、多くの場合、依存SQLが無効になり、以降の実行で再度解析されることになります。

順序番号のキャッシュ

頻繁に更新される順序番号に十分なキャッシュ領域を割り当てると、ディクショナリ・キャッシュ・ロックの回数が大幅に減るため、スケーラビリティが向上します。

各順序に対するキャッシュ・エントリ数を構成するには:

  • CREATE SEQUENCEまたはALTER SEQUENCE文で、CACHEキーワードを使用します。

カーソル・アクセスの制御

使用しているアプリケーション・ツールによっては、カーソル・アクセスを制御することで、アプリケーションの解析コールの実行頻度を制御できます。

アプリケーションが、カーソルをクローズする、または新しいSQL文に既存のカーソルを再利用する頻度は、セッションで使用されるメモリー量と、時には、そのセッションで実行される解析の量にも影響を与えます。(異なるSQL文の)カーソルをクローズまたは再利用するアプリケーションは、カーソルをオープンした状態を保つアプリケーションほどセッション・メモリーを必要としません。逆に、そのようなアプリケーションでは、解析コールがより多く実行されるため、より多くのCPUおよびデータベース・リソースを使用する可能性があります

頻繁に実行されないSQL文に関連するカーソルをクローズしたり、他の文に再利用できるのは、その文を再実行(および再解析)する可能性が低いからです。再実行されるSQL文を含むカーソルがクローズまたは別の文に再利用される場合は、追加の解析コールが必要になります。カーソルがオープンされた状態であれば、解析コールを発行するためのオーバーヘッドを発生させずに、カーソルを再利用できます。

カーソル・アクセスを制御する方法は、アプリケーション開発ツールにより異なります。この項では、Oracle Databaseツールで使用される方法を説明します。

関連項目:

各ツールの詳細は、ツール固有のマニュアルを参照してください

OCIを使用したカーソル・アクセスの制御

Oracle Call Interface (OCI)を使用する場合、再実行するカーソルはクローズおよび再オープンしないでください。そのかわりに、カーソルをオープンしたままにし、実行前にリテラル値をバインド変数に変更してください。

既存のSQL文が今後再実行される場合は、新しいSQL文に文ハンドルを再利用しないようにしてください。

Oracleプリコンパイラを使用したカーソル・アクセスの制御

Oracleプリコンパイラを使用する場合、プリコンパイラ句を設定して、いつカーソルをクローズするかを制御できます。Oracleモードでは、句は次のようになります。

  • HOLD_CURSOR = YES

  • RELEASE_CURSOR = NO

  • MAXOPENCURSORS = desired_value

プリコンパイラ句は、プリコンパイラ・コマンドライン上またはプリコンパイラ・プログラム内で指定できます。ANSIモードでは、HOLD_CURSORRELEASE_CURSORの値が切り替えられますが、これはお薦めしません。

関連項目:

これらの句の詳細は、使用している言語のプリコンパイラ・マニュアルを参照してください

SQLJを使用したカーソル・アクセスの制御

SQL文を用意し、バインド変数に新しい値を使用して文を再実行します。カーソルは、セッション中はオープンのままです。

ノート:

Oracle Database 12cリリース2 (12.2)以降、サーバー側のSQLJコードはサポートされません。つまり、ストアド・プロシージャ、関数およびトリガー内でSQLJコードを使用することはできません。
JDBCを使用したカーソル・アクセスの制御

新しいリテラル値は、再実行のためにカーソルにバインドできるので、カーソルを再実行する場合は、カーソルをクローズしないでください。別の方法として、JDBCはsetStmtCacheSize()メソッドを使用してJDBCクライアント内にSQL文キャッシュを提供しています。このメソッドを使用して、JDBCはJDBCプログラムに対してローカルなSQL文キャッシュを作成します。

関連項目:

JDBC SQL文キャッシュの使用方法の詳細は、『Oracle Database JDBC開発者ガイド』を参照してください

Oracle Formsを使用したカーソル・アクセスの制御

Oracle Formsを使用すると、実行時、トリガー・レベルまたはフォーム・レベルで、カーソル・アクセスの一部の局面を制御できます。

永続的な接続の維持

中間層を持つ大きなOLTPアプリケーションでは、データベース・リクエストごとに接続と切断を行うのではなく、接続を維持するようにします。永続的な接続を維持することで、ラッチなどのCPUリソースとデータベース・リソースが節約されます。

共有プールの構成

この項では、共有プールの構成方法を説明しており、内容は次のとおりです。

共有プールのサイズ設定

新規にデータベース・インスタンスを構成する場合は、共有プール・キャッシュの適切なサイズを把握することは困難です。通常、DBAはキャッシュ・サイズの最初の見積りを行い、次にインスタンス上で代表的なワークロードを実行し、関連する統計を調べて、キャッシュが過小構成か過大構成かを調べます。

OLTPアプリケーションの多くでは、共有プール・サイズはアプリケーション・パフォーマンスにとって重要な要因です。意思決定支援システム(DSS)のような、ごく少数の不連続なSQL文を発行するアプリケーションでは、共有プールのサイズはそれほど重要ではありません。

共有プールが小さすぎると、使用可能領域の限度を補うために、追加リソースを使用することになります。このため、CPUとラッチングのリソースが使用され、競合が発生します。共有プールは、頻繁にアクセスされるオブジェクトをキャッシュするためにちょうど十分な大きさであることが理想的です。共有プールに大量の空きメモリーを持つことは、メモリーの無駄になります。データベースの稼働後に統計を調べる際、これらの点についてワークロード内に該当する箇所がないか確認してください。

この項では、共有プールのサイズ設定方法を説明しており、内容は次のとおりです。

ライブラリ・キャッシュ統計の使用

共有プールをサイズ設定するときの目標は、メモリーを割り当てすぎずに、複数回実行されるSQL文をライブラリ・キャッシュにキャッシュすることです。この目標を達成するには、次のライブラリ・キャッシュ統計を調査します。

  • RELOADS

    V$LIBRARYCACHEビューのRELOADS列には、以前にキャッシュされ、キャッシュから除去されたSQL文のリロード(または解析)の量が表示されます。アプリケーションで効果的にSQLが再利用され、共有プール・サイズが最適なシステムで実行されている場合、この統計はゼロに近い値を示します。

  • INVALIDATIONS

    V$LIBRARYCACHEビューのINVALIDATIONS列は、ライブラリ・キャッシュのデータが無効にされ、再解析された回数を示しています。この統計は、ピーク・ロード中のOLTPシステム上では特に、ゼロに近い値となります。つまり、共有できるSQL文が、ある操作(DDLなど)により無効にされたことを意味します。

  • ライブラリ・キャッシュ・ヒット率

    ライブラリ・キャッシュ・ヒット率は、ライブラリ・キャッシュの状態に関する全般的なインジケータです。この値は、ハード解析率や、共有プールまたはライブラリ・キャッシュのラッチ競合があるかどうかなど、その他の統計とともに考慮する必要があります。

  • 共有プールの空きメモリー量

    共有プールの空きメモリー量を表示するには、V$SGASTATパフォーマンス・ビューを問い合せます。空きメモリーは、システム上に再解析を発生させない程度で、できるだけ少なくすることが理想的です。

次の各項では、これらのライブラリ・キャッシュ統計を表示および調査する方法を説明します。

V$LIBRARYCACHEビューの使用

ライブラリ・キャッシュ・アクティビティを反映する統計を監視するには、V$LIBRARYCACHEビューを使用します。これらの統計は、最新のデータベース・インスタンス起動後のすべてのライブラリ・キャッシュのアクティビティを反映しています。

このビューの各行には、ライブラリ・キャッシュ内に保持される項目の1つに対応する統計が収録されます。各行ごとに記述される項目は、NAMESPACE列の値によって識別されます。次のNAMESPACE値を持つ行は、SQL文とPL/SQLブロックのライブラリ・キャッシュのアクティビティを反映します。

  • SQL AREA

  • TABLE/PROCEDURE

  • BODY

  • TRIGGER

他のNAMESPACE値を持つ行は、Oracle Databaseが依存関係のメンテナンスのために使用するオブジェクト定義に対するライブラリ・キャッシュのアクティビティを反映します。

例14-1に、各ネームスペースを個別に調査するためのこのビューの問合せを示します。

例14-1 V$LIBRARYCACHEビューの問合せ

SELECT namespace, pins, pinhits, reloads, invalidations
  FROM V$LIBRARYCACHE
 ORDER BY namespace;

この問合せの出力例を次に示します。

NAMESPACE             PINS    PINHITS    RELOADS INVALIDATIONS
--------------- ---------- ---------- ---------- -------------
BODY                  8870       8819          0             0
CLUSTER                393        380          0             0
INDEX                   29          0          0             0
OBJECT                   0          0          0             0
PIPE                 55265      55263          0             0
SQL AREA          21536413   21520516      11204             2
TABLE/PROCEDURE   10775684   10774401          0             0
TRIGGER               1852       1844          0             0

この例の出力は、次のことを示しています。

  • SQL AREAのネームスペースには、21,536,413回の実行があります。

  • これらの実行のうち11,204回ではライブラリ・キャッシュ・ミスが発生しており、データベースで、文またはブロックを暗黙的に再解析するか、ライブラリ・キャッシュから除去されているため、オブジェクト定義をリロードする必要があります。

  • SQL文は2回無効化されたため、再度ライブラリ・キャッシュ・ミスが発生しています。

ノート:

この問合せにより、インスタンスの起動からデータが戻されます。かわりに、ある期間に収集された統計を使用すると、より的確に問題を特定できます。ある期間の情報を収集する方法の詳細は、「自動パフォーマンス診断」を参照してください。

関連項目:

V$LIBRARYCACHEビューの詳細は、『Oracle Databaseリファレンス』を参照してください

ライブラリ・キャッシュ・ヒット率の計算

ライブラリ・キャッシュ・ヒット率を計算するには、次の計算式を使用します。

Library Cache Hit Ratio = sum(pinhits) / sum(pins)

ライブラリ・キャッシュ・ヒット率の式を例14-1に適用すると、次のライブラリ・キャッシュ・ヒット率になります。

SUM(PINHITS)/SUM(PINS)
----------------------
            .999466248

この例では、ヒット率が約99.94%で、実行の0.06%のみが再解析されたことを意味します。

共有プールの空きメモリー量の表示

共有プールの空きメモリー量は、V$SGASTATビューでレポートされます。

例14-2に、このビューの問合せを示します。

例14-2 V$SGASTATビューの問合せ

SELECT *
  FROM V$SGASTAT
 WHERE name = 'free memory'
   AND pool = 'shared pool';

この問合せの出力例を次に示します。

POOL        NAME                            BYTES
----------- -------------------------- ----------
shared pool free memory                   4928280

共有プール内に使用可能な空きメモリーが常にある場合は、サイズを増やしても、効果はほとんど、またはまったくありません。ただし、共有プールがいっぱいというだけでは、問題があるとはいえません。これは、適切に構成されたシステムであることを示している場合があります。

共有プールのアドバイザ統計の使用

ライブラリ・キャッシュに使用可能なメモリー量は、Oracle Databaseの解析率に大きな影響を与えます。ライブラリ・キャッシュの適切なサイズ設定に役立つよう、Oracle Databaseには、次の共有プール・アドバイザ・ビューがあります。

  • V$SHARED_POOL_ADVICE

  • V$LIBRARY_CACHE_MEMORY

  • V$JAVA_POOL_ADVICE

  • V$JAVA_LIBRARY_CACHE_MEMORY

これらの共有プール・アドバイザ・ビューから、ライブラリ・キャッシュ・メモリーについての情報を得ることができ、共有プールのサイズ変更が共有プール内のオブジェクトの除去にどのように影響するかを予測できます。これらのビューの共有プール・アドバイザ統計では、共有プール・メモリーにおけるライブラリ・キャッシュの使用率が追跡され、異なるサイズの共有プールでライブラリ・キャッシュがどのように動作するかが予測されます。これらのビューを使用することで、次のことを判断できます。

  • ライブラリ・キャッシュが使用しているメモリー量

  • 現在確保されているメモリー量

  • 共有プールの最低使用頻度(LRU)リストのメモリー量

  • 共有プールのサイズを変更することで失われる、または得られる時間

共有プール・アドバイザが有効化されていると、これらのビューには共有プール・アドバイザ統計が表示されます。アドバイザを無効化すると、統計がリセットされます。

次の各項では、これらのビューについてさらに詳しく説明します。

V$SHARED_POOL_ADVICEビューについて

V$SHARED_POOL_ADVICEビューは、様々なサイズの共有プールでの解析時間の見積りに関する情報を示します。サイズの範囲は、同じ時間間隔で、現在の共有プール・サイズまたは確保されたライブラリ・キャッシュ・メモリー量の10%のうち大きい方の値から、現在の共有プール・サイズの200%までです。間隔値は、現行の共有プール・サイズに応じて異なります。

関連項目:

V$SHARED_POOL_ADVICEビューの詳細は、Oracle Databaseリファレンスを参照してください

V$LIBRARY_CACHE_MEMORYビューについて

V$LIBRARY_CACHE_MEMORYビューは、様々なネームスペース内のライブラリ・キャッシュ・メモリー・オブジェクトに割り当てられたメモリーに関する情報を示します。メモリー・オブジェクトは、効率的に管理するために内部でメモリーをグループ化したものです。ライブラリ・キャッシュ・オブジェクトは、1つ以上のメモリー・オブジェクトで構成されます。

関連項目:

V$LIBRARY_CACHE_MEMORYビューの詳細は、Oracle Databaseリファレンスを参照してください

V$JAVA_POOL_ADVICEビューおよびV$JAVA_LIBRARY_CACHE_MEMORYビューについて

V$JAVA_POOL_ADVICEおよびV$JAVA_LIBRARY_CACHE_MEMORYビューには、Javaに使用されるライブラリ・キャッシュ・メモリーについての情報を追跡し、Javaプールのサイズ変更が解析率に及ぼす影響を予測する、Javaプール・アドバイザ統計が含まれます。

V$JAVA_POOL_ADVICEビューは、様々なプール・サイズのJavaプール内での見積り解析時間に関する情報を示します。サイズの範囲は、同じ時間間隔で、現在のJavaプール・サイズまたは確保されたJavaライブラリ・キャッシュ・メモリー量の10%のうち大きい方の値から、現在のJavaプール・サイズの200%までです。間隔値は、現行のJavaプール・サイズに応じて異なります。

関連項目:

V$JAVA_POOL_ADVICEビューおよびV$JAVA_LIBRARY_CACHE_MEMORYビューの詳細は、Oracle Databaseリファレンスを参照してください

ディクショナリ・キャッシュ統計の使用

共有プールがライブラリ・キャッシュに対して適切にサイズ設定されている場合、その設定はディクショナリ・キャッシュ・データに対しても適切なサイズであるのが普通です。

場合によっては、データ・ディクショナリ・キャッシュ上でミスが発生します。データベース・インスタンスが起動すると、データ・ディクショナリ・キャッシュにはデータがなくなります。したがって、発行されたSQL文からキャッシュ・ミスが発生する可能性があります。キャッシュに読み取られるデータが増えると、キャッシュ・ミスの可能性は減少します。最終的に、データベースは、最も頻繁に使用されるディクショナリ・データがキャッシュ内に存在する安定状態に到達します。この時点で、キャッシュ・ミスはほとんど発生しません。

V$ROWCACHEビューの各行は、データ・ディクショナリ項目について単一のタイプの統計を収録します。これらの統計は、直前のインスタンス起動以降のデータ・ディクショナリ・アクティビティを反映しています。

表14-1は、データ・ディクショナリ・キャッシュの使用と有効性を反映するV$ROWCACHEビューの中の列を示しています。

表14-1 V$ROWCACHEビューのデータ・ディクショナリ列

説明

PARAMETER

特定のデータ・ディクショナリ項目を識別します。各行で、この列の値は接頭辞dc_が付いた項目です。たとえば、ファイル記述の統計を含む行では、この列の値はdc_filesです。

GETS

対応する項目に関する情報へのリクエストの総数を示します。たとえば、ファイル記述の統計を含む行では、この列の値はファイル記述データへのリクエストの総数になります。

GETMISSES

キャッシュで満たされていないデータ・リクエストで、I/Oを必要とするものの個数を示します。

MODIFICATIONS

ディクショナリ・キャッシュ内のデータが更新された回数を示します。

例14-3に、アプリケーションの実行中、一定期間にわたって統計を監視するためのこのビューの問合せを示します。導出された列PCT_SUCC_GETSは、項目固有のヒット率と考えることができます。

例14-3 V$ROWCACHEビューの問合せ

column parameter format a21
column pct_succ_gets format 999.9
column updates format 999,999,999

SELECT parameter,
       sum(gets),
       sum(getmisses),
       100*sum(gets - getmisses) / sum(gets) pct_succ_gets,
       sum(modifications) updates
  FROM V$ROWCACHE
 WHERE gets > 0
 GROUP BY parameter;

この問合せの出力例を次に示します。

PARAMETER              SUM(GETS) SUM(GETMISSES) PCT_SUCC_GETS      UPDATES
--------------------- ---------- -------------- ------------- ------------
dc_database_links             81              1          98.8            0
dc_free_extents            44876          20301          54.8       40,453
dc_global_oids                42              9          78.6            0
dc_histogram_defs           9419            651          93.1            0
dc_object_ids              29854            239          99.2           52
dc_objects                 33600            590          98.2           53
dc_profiles                19001              1         100.0            0
dc_rollback_segments       47244             16         100.0           19
dc_segments               100467          19042          81.0       40,272
dc_sequence_grants           119             16          86.6            0
dc_sequences               26973             16          99.9       26,811
dc_synonyms                 6617            168          97.5            0
dc_tablespace_quotas         120              7          94.2           51
dc_tablespaces            581248             10         100.0            0
dc_used_extents            51418          20249          60.6       42,811
dc_user_grants             76082             18         100.0            0
dc_usernames              216860             12         100.0            0
dc_users                  376895             22         100.0            0

この例の出力は、次のことを示しています。

  • 使用済エクステント、空きエクステントおよびセグメントには、多数のミスと更新があります。つまり、データベース・インスタンスに大量の動的な領域の拡張があったことを示しています。

  • 取得成功率と実際の取得数の比較により、共有プールがディクショナリ・キャッシュ・データを適切に格納できる大きさがあることが示されています。

また、次の問合せを使用して、総合的ディクショナリ・キャッシュ・ヒット率を計算できますが、すべてのキャッシュにわたるデータを合計すると、より細かいデータの粒度は失われます。

SELECT (SUM(gets - getmisses - fixed)) / SUM(gets) "row cache"
  FROM V$ROWCACHE;
共有プールに割り当てられたメモリーの増加

共有プールのメモリー量を増やすと、ライブラリ・キャッシュ、ディクショナリ・キャッシュおよび結果キャッシュで使用可能なメモリー量も増加します。実行する前に、共有プールの統計を確認し、次のことを調査してください。

  • V$LIBRARYCACHE.RELOADS列の値がゼロに近いかどうか

  • ディクショナリ・キャッシュが頻繁にアクセスされる場合、V$ROWCACHE.GETMISSES列の合計に対するV$ROWCACHE.GETSの合計の割合が、10%または15%を下回っているかどうか(アプリケーションによって異なります)

これらのどちらの条件も満たしている場合は、共有プールが適切にサイズ設定されており、メモリーを増やしてもパフォーマンスの向上は見込めません。一方で、これらのどちらかの条件を満たしていない場合は、アプリケーションが「共有プールの使用」の説明に従って効率的に共有プールを使用している場合でも、共有プールのメモリーを増やすことを検討してください。

共有プールのサイズを大きくするには:

  • 条件を満たすまで、SHARED_POOL_SIZE初期化パラメータの値を増やします。

    このパラメータの最大値はオペレーティング・システムによって異なります。この処置によって、実行のためのSQL文とPL/SQLブロックの暗黙的な再解析が減少します。

IC - 「初期化パラメータによるサーバーの結果キャッシュ・メモリーの管理」へのリンクが必要

共有プールに割り当てられたメモリーの低減

V$LIBRARYCACHE.RELOADS列の値がゼロに近く、共有プールの空きメモリー量が少ない場合、共有プールは最も頻繁にアクセスされるデータを格納するよう適切にサイズ設定されています。共有プールの空きメモリー量が多く、このメモリーを他の場所に割り当てる場合は、共有プールのサイズを小さくすることを検討してください。

共有プールのサイズを小さくするには、次のようにします。

  • パフォーマンスが良好な状態に維持されていることを確認しながら、SHARED_POOL_SIZE初期パラメータの値を減らします。

カーソルの割当て解除

ライブラリ・キャッシュ・ミスがない場合は、CURSOR_SPACE_FOR_TIME初期化パラメータの値をTRUEに設定して、実行コールを高速化することを検討してください。このパラメータは、新しいSQL文の領域を作成するために、ライブラリ・キャッシュからカーソルの割当てを解除するかどうかを指定します。

CURSOR_SPACE_FOR_TIMEパラメータに設定されている値によって、次のようになります。

  • FALSE(デフォルト)に設定されていると、SQL文に対応付けられているアプリケーション・カーソルがオープンされているかどうかにかかわらず、ライブラリ・キャッシュからカーソルの割当てを解除できます。

    この場合は、SQL文を含むカーソルがライブラリ・キャッシュ内にあることを検証する必要があります。

  • TRUEに設定すると、その文に関連するすべてのアプリケーション・カーソルがクローズされる場合のみカーソルの割当てを解除できます。

    この場合、関連するアプリケーション・カーソルがオープンしている間はそのカーソルの割当てを解除できないため、カーソルがライブラリ・キャッシュ内にあるかどうかを確認する必要はありません。

パラメータの値をTRUEに設定することで、Oracle Database側の時間が少し短縮されるので、いくらか実行コールのパフォーマンスが改善する可能性があります。この値は、対応付けられているアプリケーション・カーソルがクローズされるまでカーソルの割当て解除も防ぎます。

次の場合は、CURSOR_SPACE_FOR_TIMEパラメータの値をTRUEに設定しないでください。

  • 実行コールでライブラリ・キャッシュ・ミスが見つかった場合

    ライブラリ・キャッシュ・ミスは、共有プールが十分大きくないので同時にオープンしている全カーソルの共有SQL領域を保持できないことを示しています。共有プールに新しいSQL文のための領域が十分になく、このパラメータの値がTRUEに設定されている場合は、文が解析されず、Oracle Databaseにより、共有メモリーが不足していることを示すエラーが戻されます。

  • 各ユーザーがプライベートSQL領域に使用可能なメモリー量が少ない場合

    また、この値は、オープンしているカーソルに対応付けられているプライベートSQL領域の割当て解除も防ぎます。同時にオープンしているすべてのカーソルのプライベートSQL領域によって使用可能メモリーがいっぱいになり、新しいSQL文の領域がない場合は、文が解析されず、Oracle Databaseにより、メモリー不足を示すエラーが戻されます。

共有プールに新しいSQL文のための領域が十分になく、このパラメータの値がFALSEに設定されている場合は、Oracle Databaseにより、既存のカーソルの割当てが解除されます。カーソルの割当てを解除するとライブラリ・キャッシュ・ミスが後で発生しますが(カーソルが再度実行される場合)、SQL文を解析できないためにアプリケーションが停止するというエラーよりも望ましい対処と言えます。

セッション・カーソルのキャッシュ

セッション・カーソル・キャッシュには、SQLおよびPL/SQL(再帰的SQLを含む)のクローズされたセッション・カーソルが含まれます。フォーム間で切替えを行うと、最初のフォームに関連するすべてのセッション・カーソルがクローズされるため、このキャッシュは、Oracle Formsが使用されているアプリケーションで有用です。アプリケーションから何度も同じSQL文で解析コールが発行される場合、セッション・カーソルの再オープンによりパフォーマンスが低下することがあります。カーソルを再使用することにより、データベースの分析時間が削減されるため、結果として全体的な実行時間が短縮されます。

この項では、セッション・カーソル・キャッシュについて説明しており、内容は次のとおりです。

セッション・カーソル・キャッシュについて

セッション・カーソルは、共有子カーソルのインスタンス化を表し、特定のセッションの共有プールに格納されます。各セッション・カーソルには、インスタンス化した子カーソルへの参照が格納されます。

Oracle Databaseでは、ライブラリ・キャッシュをチェックして、特定の文に対して3回以上の解析リクエストが発行されたかどうかを識別します。カーソルが3回クローズされている場合は、文に関連するセッション・カーソルをキャッシュする必要があると推定し、カーソルをセッション・カーソル・キャッシュに移動します。

同じセッションでSQL文の解析リクエストが続けて出されると、共有カーソルへのポインタの配列が検索されます。ポインタが見つかると、データベースはポインタを逆参照して共有カーソルが存在するかどうか特定します。カーソルをキャッシュから再使用するために、キャッシュ・マネージャはキャッシュされたカーソルの状態が現在のセッションとシステム環境に適合するかどうか確認します。

ノート:

キャッシュ・カーソルの再使用はハード解析ではありませんが、まだ解析として登録されています。

LRUのアルゴリズムでは、必要に応じてセッション・カーソル・キャッシュ内の項目を除去し、新しい項目のための空間を作成します。また、キャッシュは内部の時間ベースのアルゴリズムを使用して、一定時間アイドル状態になっているカーソルを除去します。

セッション・カーソル・キャッシュの有効化

次の初期化パラメータは、セッション・カーソル・キャッシュに関連します。

  • SESSION_CACHED_CURSORS

    このパラメータは、1セッション当たりのクローズされたキャッシュ・カーソルの最大数を設定します。デフォルト値は50です。このパラメータは、同じセッションで繰り返し実行される文について、キャッシュからカーソルを再利用する場合に使用します。

  • OPEN_CURSORS

    このパラメータは、セッションで同時に開くことができるカーソルの最大数を指定します。たとえば、値を1000に設定すると、各セッションは一度に最大1000個のカーソルを開くことができます。

これらのパラメータは独立しています。たとえば、SESSION_CACHED_CURSORSパラメータの値をOPEN_CURSORSパラメータの値より大きく設定できますが、これは、セッション・カーソルがオープンの状態でキャッシュされないためです。

セッション・カーソル・キャッシュを有効化するには:

  1. キャッシュに保持するセッション・カーソルの最大数を決定します。

  2. 次のいずれかの操作を行います。

    • 静的キャッシュを有効化するには、SESSION_CACHED_CURSORSパラメータの値を前のステップで決定した数値に設定します。

    • 動的キャッシュを有効化するには、次の文を実行します。

      ALTER SESSION SET SESSION_CACHED_CURSORS = value;
      
セッション・カーソル・キャッシュのサイズ設定

セッション・カーソル・キャッシュがデータベース・インスタンスに対して適切にサイズ設定されているかどうかを確認するには、V$SESSTATビューを使用します。

セッション・カーソル・キャッシュのサイズを設定するには:

  1. V$SESSTATビューを問い合せて、現在特定のセッションにキャッシュされているカーソルの数を特定します。

  2. V$SESSTATビューを問い合せて、セッション・カーソル・キャッシュでカーソルが検出された解析コールの割合を取得します。

  3. 次の内容に当てはまる場合は、SESSION_CACHED_CURSORSパラメータの値を増やすことを検討してください。

    • セッション・カーソル・キャッシュ数が最大値に近い

    • セッション・カーソル・キャッシュのヒットの割合が合計解析数と比較して低い

    • アプリケーションが同じ問合せに対して繰り返し解析コールを実行する

例14-4に、このビューの問合せを2つ示します。

例14-4 V$SESSTATビューの問合せ

次の問合せでは、現在特定のセッションにキャッシュされているカーソルの数がわかります。

SELECT a.value curr_cached, p.value max_cached,
       s.username, s.sid, s.serial#
  FROM v$sesstat a, v$statname b, v$session s, v$parameter2 p
 WHERE a.statistic# = b.statistic#  and s.sid=a.sid and a.sid=&sid
   AND p.name='session_cached_cursors'
   AND b.name = 'session cursor cache count';

この問合せの出力例を次に示します。

CURR_CACHED MAX_CACHED USERNAME   SID    SERIAL#
----------- ---------- -------- ----- ----------
         49 50         APP         35        263

この結果は、セッション35で現在キャッシュされているカーソルの数が最大値に近いことを示しています。

次の問合せでは、セッション・カーソル・キャッシュでカーソルが検出された解析コールの割合がわかります。

SELECT cach.value cache_hits, prs.value all_parses,
       round((cach.value/prs.value)*100,2) as "% found in cache"
  FROM v$sesstat cach, v$sesstat prs, v$statname nm1, v$statname nm2
 WHERE cach.statistic# = nm1.statistic#
   AND nm1.name = 'session cursor cache hits'
   AND prs.statistic#=nm2.statistic#
   AND nm2.name= 'parse count (total)'
   AND cach.sid= &sid and prs.sid= cach.sid;

この問合せの出力例を次に示します。

CACHE_HITS ALL_PARSES % found in cache
---------- ---------- ----------------
        34        700             4.57

この結果は、セッション35のセッション・カーソル・キャッシュでのヒット数が、解析の合計数と比較して低いことを示しています。

この例では、SESSION_CACHED_CURSORSパラメータの値を100に設定すると、パフォーマンスが向上する可能性があります。

カーソルの共有

SQL解析の内容では、同一文とは、テキストが他の文と空白、大文字小文字の区別、コメントも含めて完全に同一であるSQL文を指します。類似文とは、一部のリテラル値を除いて同一である文です。

解析フェーズでは、文のテキストを共有プールの文と比較して、その文を共有できるかどうかを判断します。CURSOR_SHARING初期化パラメータの値がEXACT (デフォルト値)に設定されていて、共有プールの文が同一でない場合、データベースではSQL領域は共有されません。かわりに、各SQL文には、その文のリテラルに基づいた独自の親カーソルと独自の実行計画があります。

この項では、カーソルの共有方法を説明しており、内容は次のとおりです。

カーソル共有について

SQL文がバインド変数よりもリテラルを使用する場合、CURSOR_SHARING初期化パラメータの値をFORCEに設定すると、データベースはリテラルをシステム生成のバインド変数と置き換えることができます。この方法を使用すると、データベースで共有SQL領域の親カーソルの数を低減できる場合があります。

CURSOR_SHARINGパラメータの値がFORCEに設定されている場合、解析フェーズにおいて、データベースで次のステップが実行されます。

  1. 共有プールでの同一文の検索。

    同一文が見つかった場合、データベースは次のステップをスキップし、ステップ3に進みます。そうでない場合は、データベースは次のステップに進みます。

  2. 共有プールでの類似文の検索。

    類似文が見つからない場合は、データベースはハード解析を実行します。類似文が見つかった場合は、データベースは次のステップに進みます。

  3. 続けて解析フェーズの残りのステップを行い、既存の文の実行計画を新しい文に適用できることを確認します。

    計画を適用できない場合は、データベースはハード解析を実行します。計画が適用できる場合は、データベースは次のステップに進みます。

  4. 文のSQL領域の共有。

データベースにより実行される様々なチェックの詳細は、「SQL共有基準」を参照してください。

カーソル共有の強制

ベスト・プラクティスは、共有可能なSQLを記述し、CURSOR_SHARING初期化パラメータにデフォルト値のEXACTを使用することです。Oracle Databaseではデフォルトで、適応カーソル共有機能が使用され、バインド変数を含む1つのSQL文が複数の実行計画を使用できるようになります。ただし、バインド変数ではなくリテラルを使用する類似文が多数あるアプリケーションでは、CURSOR_SHARINGパラメータの値をFORCEに設定するとカーソル共有が改善され、結果としてメモリー使用量が減少し、解析時間が削減され、ラッチの競合が減少します。共有プールの文がリテラルの値のみ異なる場合で、ライブラリ・キャッシュ・ミスの回数が多いためにレスポンス時間が遅くなっている場合には、このアプローチを検討してください。この場合は、CURSOR_SHARINGパラメータの値をFORCEに設定することによりカーソル共有が最大化され、適応カーソル共有を使用して、異なるリテラル値の範囲に基づき、複数の実行パスを生成できます。

CURSOR_SHARINGパラメータの値をEXACTに設定してストアド・アウトラインを生成すると、データベースはリテラルを使用して生成されたストアド・アウトラインを使用しません。この問題を回避するには、CURSOR_SHARINGFORCEに設定してアウトラインを生成し、CREATE_STORED_OUTLINESパラメータを使用します。

CURSOR_SHARINGパラメータの値をFORCEに設定すると、次のデメリットがあります。

  • データベースは、共有プール内で類似文を検索するために、ソフト解析の間に追加作業を実行する必要があります。

  • SELECT文にリテラルを含む選択された式の最大長(DESCRIBEからの戻り値)が増加します。ただし、戻されたデータの実際の長さは変わりません。

  • スター型変換はサポートされません。

CURSOR_SHARINGパラメータの値をFORCEに設定すると、データベースは各個別のSQL文に1つの親カーソルと1つの子カーソルを使用します。同じ文の各実行に同じ計画が使用されます。たとえば、次のSQL文について検討します。

SELECT *
  FROM hr.employees
 WHERE employee_id = 101;

CURSOR_SHARINGパラメータの値がFORCEに設定されている場合、データベースはこの文をバインド変数を含むかのように最適化し、バインド照合を使用してカーディナリティを予測します。

ノート:

Oracle Database 11gリリース2以上では、CURSOR_SHARINGパラメータの値をSIMILARに設定することは推奨されていません。かわりに、適応カーソル共有を使用することを検討してください。

関連項目:

  • CURSOR_SHARING初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください

  • 適応カーソル共有の詳細は、Oracle Database SQLチューニング・ガイドを参照してください

除去防止のためのラージ・オブジェクトの保存

エントリが共有プールにロードされた後は、それを移動することはできません。エントリがロードされ、除去されると、空きメモリーが断片化されることもあります。共有SQL領域と共有PL/SQL領域は、データベース・バッファに類似のLRUアルゴリズムに従って共有プールから除去されます。パフォーマンスを改善したり、再解析が行われないようにするために、サイズの大きいSQL領域またはPL/SQL領域が古くなって共有プールから除去されないようにすることが可能です。

DBMS_SHARED_POOLパッケージを使用すると、オブジェクトが共有メモリー内に維持されるため、これらのオブジェクトは通常のLRUメカニズムによって除去されることはありません。DBMS_SHARED_POOLパッケージを使用し、SQL領域とPL/SQL領域をメモリーの断片化が発生する前にロードすると、オブジェクトはメモリー内に維持されます。こうすることによって、メモリーが確実に使用可能になり、SQL領域とPL/SQL領域の除去後にこれらの領域にアクセスする場合に、ユーザーのレスポンス時間が突然低下するのを防ぐことができます。

次のような場合には、DBMS_SHARED_POOLパッケージの使用を検討してください。

  • STANDARDDIUTILパッケージなどの大きなPL/SQLオブジェクトをロードする場合。

    大きなPL/SQLオブジェクトがロードされる場合で、大きなオブジェクト用に領域を確保するために小さなオブジェクトを共有プールから除去する必要がある場合は、ユーザーのレスポンス時間に影響が現れます。場合によっては、ラージ・オブジェクトをロードするためのメモリーが不足している場合があります。

  • コンパイルしたトリガーを共有プールで頻繁に使用される表に維持する場合。

  • 順序をサポートする場合。

    共有プールから順序が除去されると、順序番号が失われます。DBMS_SHARED_POOLパッケージは、共有プール内に順序を保持し、順序番号の消失を防ぎます。

SQL領域またはPL/SQL領域を共有メモリー内に維持するには:

  1. メモリー内に確保しておくパッケージまたはカーソルを決定します。

  2. データベースを起動します。

  3. DBMS_SHARED_POOL.KEEPパッケージをコールしてオブジェクトを確保します。

    この手順により、確保されているオブジェクトがロードされる前にシステムの共有メモリーが不足しないことが保証されます。オブジェクトをデータベース・インスタンスの早い時期に確保することにより、大きなメモリー領域を共有プールの中央に保持するために発生する可能性のある、メモリーの断片化を防ぐことができます。

関連項目:

DBMS_SHARED_POOLプロシージャの使用方法の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください

予約プールの構成

Oracle Databaseでは、非常に大きいメモリーのリクエストは小さいチャンクに分割されますが、システムによっては、(デフォルトの最小予約プール割当てが4,400バイトであるのに対して5KBを超えるような)メモリーの連続チャンクの検索が必要な場合があります。

共有プールに十分な空き領域がない場合は、このリクエストを満たすための十分な空きメモリーを検索する必要があります。この操作では、長期間にわたってラッチ・リソースが保持されるため、メモリー割当てで他の同時動作に対して多少の影響が生じる可能性があります。

これを回避するため、共有プールに十分な領域がない場合に、Oracle Databaseが使用できる小さいメモリー領域がデフォルトで、共有プールに内部的に予約されます。この予約プールによって、大きいチャンクの割当てがより効率的に行われます。このメモリーは、PL/SQLおよびトリガーのコンパイルなどの操作や、Javaオブジェクトのロード時の一時領域に使用できます。予約プールから割り当てられたメモリーが解放されると、予約プールに戻されます。

大きい割当ての場合、Oracle Databaseは次の順序で共有プールへの領域の割当てを試行します。

  1. 共有プールの予約されていない部分。

  2. 予約プール。

    共有プールの予約されていない部分に十分な領域がない場合は、予約プールに十分な領域があるかどうかチェックされます。

  3. メモリー。

    共有プールの予約されていない部分と予約された部分に十分な領域がない場合は、Oracle Databaseは割当てのために十分なメモリーの解放を試みます。次に、データベースにより、共有プールの予約されていない部分と予約されている部分が再試行されます。

この項では、予約プールの構成方法を説明しており、内容は次のとおりです。

予約プールのサイズ設定

通常、Oracle Databaseが予約プールで予約するデフォルトの領域量を変更する必要はありません。ただし、極端に大きなメモリー割当てのために、共有プールに領域を確保しておくことが必要な場合もあります。

予約プール・サイズは、SHARED_POOL_RESERVED_SIZE初期化パラメータの値を設定することで指定できます。SHARED_POOL_RESERVED_SIZEパラメータのデフォルト値は、SHARED_POOL_SIZEパラメータの5%です。

予約プールのメモリーを過剰に予約することはできないため、SHARED_POOL_RESERVED_SIZEパラメータの値をSHARED_POOL_SIZEパラメータの半分を超える値に設定すると、Oracle Databaseからエラーが戻されます。使用可能なオペレーティング・システムのメモリー容量も共有プールのサイズを制約する場合があります。一般的に、SHARED_POOL_RESERVED_SIZEパラメータの値は、SHARED_POOL_SIZEパラメータの10%以下に設定します。ほとんどのシステムにおいて、共有プールが適切にチューニングされていれば、この値で十分です。この値を大きくすると、データベースにより追加のメモリーが共有プールから取得され、より小さな割当てに使用可能な予約されていない共有プールのメモリー量が減少します。

これらのパラメータをチューニングする際は、V$SHARED_POOL_RESERVEDビューの統計を使用します。SGAのサイズを大きくするための空きメモリーが豊富にあるシステムでは、REQUEST_MISSES統計の値をゼロにする必要があります。オペレーティング・システム・メモリーによる制約があるシステムの場合は、REQUEST_FAILURES統計をゼロにするか、少なくともこの値が増加しないようにすることが目標です。これらの目標値を達成できない場合は、SHARED_POOL_RESERVED_SIZEパラメータの値を増やしてください。また、予約リストは共有プールから取られるため、SHARED_POOL_SIZEパラメータの値も同じだけ増やします。

V$SHARED_POOL_RESERVED固定ビューを使用すると、SHARED_POOL_SIZEパラメータの値が小さすぎる場合を示すこともできます。これは、REQUEST_FAILURES統計がゼロより大きい場合および増加しているような場合です。予約リストが有効化されている場合は、SHARED_POOL_RESERVED_SIZEパラメータの値を減らします。予約リストが有効化されていない場合は、「共有プールに割り当てられたメモリーの増加」で説明されているように、SHARED_POOL_SIZEパラメータの値を増やします。

予約プールに割り当てられたメモリーの増加

REQUEST_FAILURES統計の値がゼロより大きい場合および増加している場合は、予約プールが小さすぎます。この場合は、予約プールに使用可能なメモリー量を増やします。

ノート:

予約リストで使用可能なメモリー量を増やしても、予約リストからメモリーを割り当てないユーザーに影響はありません。

予約プールのサイズを大きくするには:

  • SHARED_POOL_RESERVED_SIZEおよびSHARED_POOL_SIZE初期化パラメータの値を適宜増やします。

    これらのパラメータに関して選択する値は、「予約プールのサイズ設定」で説明されているように、システムのSGAのサイズ制約によって異なります。

予約プールに割り当てられたメモリーの低減

次のような場合は、予約プールが大きすぎます。

  • REQUEST_MISSES統計がゼロの場合または増加しない場合

  • FREE_SPACE統計の最小値がSHARED_POOL_RESERVED_SIZEの50%以上になる場合

これらの条件のいずれかに当てはまる場合は、予約プールに使用可能なメモリー量を減らします。

予約プールのサイズを小さくするには:

  • SHARED_POOL_RESERVED_SIZE初期化パラメータの値を減らします。

ラージ・プールの構成

共有プールとは異なり、ラージ・プールにはLRUリストがありません。Oracle Databaseは、ラージ・プールからオブジェクトを除去しようとしません。データベース・インスタンスがOracle Databaseの次の機能のいずれかを使用する場合は、ラージ・プールの構成を検討してください。

  • 共有サーバー

    共有サーバー・アーキテクチャでは、各クライアント・プロセスのセッション・メモリーが共有プールに含まれています。

  • パラレル問合せ

    パラレル問合せでは、共有プール・メモリーを使用してパラレル実行メッセージ・バッファをキャッシュします。

  • Recovery Manager

    Recovery Manager (RMAN)は、バックアップおよびリストア操作時に共有プールを使用してI/Oバッファをキャッシュします。I/Oサーバー・プロセス、バックアップおよびリストア操作では、Oracle Databaseは数百KB単位でバッファを割り当てます。

この項では、共有サーバー・アーキテクチャにラージ・プールを構成する方法を説明しており、内容は次のとおりです。

関連項目:

  • ラージ・プールの詳細は、『Oracle Database概要』を参照してください

  • Recovery Managerを使用する場合のラージ・プールのサイズ設定の詳細は、『Oracle Databaseバックアップおよびリカバリ・ユーザーズ・ガイド』を参照してください

共有サーバー・アーキテクチャでのラージ・プールの構成

Oracle Databaseでは共有サーバー・セッションに共有プールからメモリーを割り当てるため、ライブラリ・キャッシュとデータ・ディクショナリ・キャッシュに使用可能な共有プール・メモリーの量が減少します。別のプールから共有サーバー・セッション・メモリーを割り当てると、共有SQLのキャッシュ用に共有プールを予約できます。

共有サーバー・アーキテクチャのユーザー・グローバル領域(UGA)の割当てには、ラージ・プールの使用をお薦めします。共有プールのかわりにラージ・プールを使用すると、共有プールの断片化が減少し、共有SQLキャッシュの縮小によるパフォーマンス・オーバーヘッドがなくなります。

デフォルトでは、ラージ・プールは構成されません。ラージ・プールを構成しない場合、共有プールは、共有サーバーのユーザー・セッション・メモリーに使用されます。共有サーバー・アーキテクチャを使用する際は、ラージ・プールを構成した場合でも、Oracle Databaseでは、共有プールから各構成セッションに一定量のメモリー(約10KB)が割り当てられます。どちらの場合も、共有プールのサイズを適宜大きくすることを検討してください。

ノート:

共有サーバーの使用により共有メモリーの使用が増加するとしても、合計のメモリー使用量は減少します。これは、プロセス数が減少するので、専用サーバー環境と比較した場合に共有サーバーではPGAメモリーの使用量が減るためです。

ヒント:

データベースで許可される同時共有サーバー・セッションの最大数を指定するには、CIRCUITS初期化パラメータを使用します。

ヒント:

共有サーバーを使用したソート操作でパフォーマンスが最大になるよう、SORT_AREA_SIZEおよびSORT_AREA_RETAINED_SIZE初期化パラメータの値を同じ値に設定します。これによって、ソート結果をディスクに書き込むのではなくラージ・プールに留めておけます。

パラレル問合せ用のラージ・プールの構成

パラレル問合せは、自動メモリー管理または自動共有メモリー管理が有効ではない場合、共有プール・メモリーを使用してパラレル実行メッセージ・バッファをキャッシュします。パラレル実行メッセージ・バッファの共有プールでのキャッシュによってそのワークロードが増加し、断片化が引き起こされるおそれがあります。

パフォーマンスへのマイナスの影響をできるかぎり避けるため、パラレル問合せの使用時は、SGAメモリーを手動で管理しないことをお薦めします。かわりに、自動メモリー管理または自動共有メモリー管理を有効にして、パラレル実行メモリー・バッファのキャッシュにラージ・プールが使用されるようにします。

ラージ・プールのサイズ設定

ラージ・プールに共有サーバー関連のUGAを格納する際は、Oracle Databaseにより使用されるUGAの正確な量はアプリケーションによって異なります。各アプリケーションは、必要なセッション情報メモリー量がそれぞれ異なり、ラージ・プールの構成はメモリー要件を反映する必要があります。

Oracle Databaseでは、セッションに使用されたメモリーの統計が収集され、V$SESSTATビューに格納されます。表14-2に、セッションUGAメモリーを反映するこのビューの統計を示します。

表14-2 V$SESSTATビューのメモリー統計

統計 説明

session UGA memory

セッションに割り当てられたメモリー量(バイト単位)が表示されます。

session UGA memory max

これまでにセッションに割り当てられた最大メモリー量(バイト単位)が表示されます。

このビューを使用してラージ・プールの適切なサイズを判断する方法は2つあります。1つは、同時にアクティブとなるセッションの数を基準にラージ・プールのサイズを構成する方法です。これを実行するには、一般的なユーザーのUGAメモリー使用状況を観察し、その量にユーザー・セッションの見積り数を乗算します。たとえば、一般的なユーザー・セッションのセッション情報を格納するために、共有サーバーに200Kから300Kが必要で、同時にアクティブになるユーザー・セッションが100になると見込まれる場合、ラージ・プールを30MBに構成します。

もう1つは、すべてのユーザー・セッションによって使用される合計メモリーおよび最大メモリーを計算する方法です。例14-5に、これを実行するためのV$SESSTATビューおよびV$STATNAMEビューにおける2つの問合せを示します。

例14-5 V$SESSTATビューおよびV$STATNAMEビューの問合せ

アプリケーションの実行中に、次の問合せを発行します。

SELECT SUM(value) || ' bytes' "total memory for all sessions"
  FROM V$SESSTAT, V$STATNAME
 WHERE name = 'session uga memory'
   AND V$SESSTAT.STATISTIC# = V$STATNAME.STATISTIC#;
SELECT SUM(value) || ' bytes' "total max mem for all sessions"
  FROM V$SESSTAT, V$STATNAME
 WHERE name = 'session uga memory max'
   AND V$SESSTAT.STATISTIC# = V$STATNAME.STATISTIC#;

また、これらの問合せでは、V$STATNAMEビューから選択して、session memorymax session memoryの内部識別子を取得します。

これらの問合せの出力例を次に示します。

TOTAL MEMORY FOR ALL SESSIONS
-----------------------------
157125 BYTES
TOTAL MAX MEM FOR ALL SESSIONS
------------------------------
417381 BYTES

最初の問合せの結果は、現在、全セッションに割り当てられているメモリーは157,125バイトであることを示しています。この値は、セッションがデータベースに接続されている方法にその位置が依存するメモリーの全体量です。セッションが専用サーバー・プロセスで接続されている場合、このメモリーはユーザー・プロセスのメモリーの一部です。セッションが共有サーバー・プロセスで接続されている場合、このメモリーは共有プールの一部です。

2番目の問合せの結果は、全セッションのメモリーの最大サイズの合計が417,381バイトであることを示しています。2番目の結果は、いくつかのセッションが最大の容量を割り当てた後でメモリーを割当て解除したため、最初の結果よりも大きくなっています。

いずれかの問合せの結果を使用して、共有プールの適切なサイズを判断します。全セッションが同時にそれらの最大割当てに到達すると予測する場合を除き、2番目の値よりも最初の値の方がより適切な見積りになります。

ラージ・プールのサイズを設定するには:
  1. V$SGASTATビューでPOOL列をチェックし、オブジェクト用のメモリーが存在するプール(共有プールまたはラージ・プール)を確認します。

  2. LARGE_POOL_SIZE初期化パラメータの値を設定します。

    このパラメータの最小値は300Kです。

ユーザー・セッションへのメモリー使用の制限

各クライアント・セッションによるSGAのメモリー使用量を制限するには、PRIVATE_SGAを使用してリソース制限を設定します。

PRIVATE_SGAによって、1セッションでSGAから使用されるメモリーのバイト数が定義されます。ただし、ほとんどのDBAはユーザー単位でのSGA消費量の制限は行わないため、このパラメータを使用することはほとんどありません。

関連項目:

PRIVATE_SGAリソース制限の設定の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

3層の接続を使用するメモリー使用の低減

接続ユーザーが非常に多数の場合は、3層の接続を実装してメモリー使用を低減することを検討してください。ロックやコミットされていないDML操作を複数のコールにわたって保持できないため、トランザクション処理(TP)モニターの使用は、純粋なトランザクション・モデルでしか実現できません。

共有サーバー環境を使用すると、次のようになります。

  • TPモニターに比べてアプリケーション設計の制限が大幅に少なくなります。

  • ユーザーがサーバーのプールを共有できるので、オペレーティング・システム・プロセス数とコンテキストの切替えが大幅に減ります。

  • 共有サーバー・モードでさらに多くのSGAが使用される場合でも総メモリー使用量が大幅に減ります。