DBMS_PROFILER
パッケージは、既存のPL/SQLアプリケーションをプロファイルし、パフォーマンス上のボトルネックを識別するためのインタフェースを提供します。またPL/SQLプロファイラ・データを収集し、永続的に保存できます。
この章では、次の項目について説明します。
概要
セキュリティ・モデル
使用上の注意
例外
このパッケージにより、収集したプロファイラ(パフォーマンス)データを使用して、パフォーマンスの向上やPL/SQLアプリケーションのコード・カバレッジの決定に役立てることができます。アプリケーション開発者は、コード・カバレッジ・データを使用して、増分テストに集中できます。
このインタフェースを使用すると、セッションで実行される指定したすべてのライブラリ・ユニットのプロファイル情報を生成できます。プロファイラは、PL/SQL仮想マシン・レベルで情報を収集します。その情報には、各行の合計実行回数、その行の実行に要した合計時間、およびその行の特定の実行に要した最小時間と最大時間が含まれています。
注意: データが収集されたPL/SQLユニットに関する、コード・カバレッジ値を推論することが可能です。 |
プロファイル情報は、データベース表に格納されています。これによってデータの問合せが可能となり、ユーザーは、カスタマイズ可能なレポート(サマリー・レポート、最新行、コード・カバレッジ・データなど)を作成できます。そして、データの分析が可能です。
PROFTAB.SQL
スクリプトは、表116-1、表116-2および表116-3にリストした列、データ・タイプおよび定義を持つ表を作成します。
表116-1 表PLSQL_PROFILER_RUNSの列
列 | データ・タイプ | 定義 |
---|---|---|
|
|
plsql_profiler_runnumberで作成される一意の実行識別子。 |
|
|
(クライアントとサーバーの相関関係に)関連する実行の実行ID。 |
|
|
実行を開始したユーザー。 |
|
|
実行の開始時間。 |
|
|
この実行に関してユーザーが指定したコメント。 |
|
|
この実行の経過時間(ナノ秒)。 |
|
|
未使用。 |
|
|
追加のコメント。 |
|
|
未使用。 |
表116-2 表PLSQL_PROFILER_UNITSの列
列 | データ・タイプ | 定義 |
---|---|---|
|
|
主キー。plsql_profiler_runsを参照。 |
|
|
主キー。内部的に生成されたライブラリ・ユニット番号。 |
|
|
ライブラリ・ユニットのタイプ。 |
|
|
ライブラリ・ユニットの所有者名。 |
|
|
ライブラリ・ユニットにおけるライブラリ・ユニット名のタイムスタンプ。 |
|
|
複数実行間にユニットで発生した変更を検出するため、将来使用される予定。 |
|
|
このユニットで経過した合計時間(ナノ秒)。プロファイラはこのフィールドを設定しませんが、分析ツールで利用するために用意されています。 |
|
|
未使用。 |
|
|
未使用。 |
表116-3 表PLSQL_PROFILER_DATAの列
列 | データ・タイプ | 定義 |
---|---|---|
|
|
主キー。一意の(生成された)実行識別子。 |
|
|
主キー。内部的に生成されたライブラリ・ユニット番号。 |
|
|
主キー。ユニット内のNULL以外の行番号。 |
|
|
行が実行された回数。 |
|
|
行の実行に要した合計時間(ナノ秒)。 |
|
|
この行の最小実行時間(ナノ秒)。 |
|
|
この行の最大実行時間(ナノ秒)。 |
|
|
未使用。 |
|
|
未使用。 |
|
|
未使用。 |
|
|
未使用。 |
Oracle Databaseのバージョン8.xには、PL/SQLデモ用スクリプトに、文脈依存のレポート・ライター(profrep.sql)のサンプルが準備されています。
Oracle Database 10gより前のバージョンでは、DBMS_PROFILER
パッケージはデータベースの作成時に自動的にロードされず、パッケージの作成にはオラクル社が提供するPROFLOAD.SQL
スクリプトが使用されていたことに注意してください。10g以降では、データベースの作成時にDBMS_PROFILER
パッケージが自動的にロードされ、PROFLOAD.SQL
は不要になりました。
プロファイラは、ユーザーにCREATE
権限があるユニットのデータのみ収集し、EXECUTE ONLY
アクセスが付与されているユニットは、このパッケージを使用してプロファイルすることはできません。通常、ユーザーがユニットをデバッグできる場合、同じユーザーがこのユニットをプロファイルできます。ただし、ユニットはDEBUG
でコンパイルされているかどうかに関係なく、プロファイルできます。プロファイル対象のモジュールを、DEBUG
でコンパイルすることをお薦めします(これによって、データベース内のユニットに関する追加情報が提供されます)。
注意: DBMS_PROFILER は、NATIVE モードでコンパイルされたプログラム・ユニットを、ユーザーにはCREATE 権限がないかのように処理します。つまり、ユーザーが出力を取得することはありません。 |
アプリケーションのパフォーマンス向上は、反復プロセスです。この反復プロセスには、次の手順が伴います。
プロファイラ・データの収集を行う1つ以上のベンチマーク・テストを使用して、アプリケーションを実行します。
プロファイラ・データを分析し、パフォーマンス上の問題を識別します。
問題を解決します。
PL/SQLプロファイラでは、実行という概念を使用してこのプロセスをサポートします。実行には、プロファイラ・データの収集を行うベンチマーク・テストを介した、アプリケーションの実行が含まれます。実行の開始および終了は、START_PROFILER
ファンクションおよびSTOP_PROFILER
ファンクションをコールして制御できます。
データを収集するには、ユーザーはまずプロファイラ・ユーザーのスキーマ内でデータベース表を作成する必要があります。PROFTAB
.SQL
スクリプトは、プロファイラ・データを継続的に格納するための表や他のデータ構造を作成します。
PROFTAB.SQL
を実行すると現行の表が削除されるので、注意してください。PROFTAB.SQL
スクリプトは、RDBMS/ADMIN
ディレクトリにあります。PL/SQLユニットの初回実行など、一部のPL/SQL操作には、実行中のPL/SQLユニットにバイト・コードをロードするカタログ表へのI/Oが含まれる場合があります。また、パッケージ・プロシージャまたはファンクションの初回コール時は、パッケージ初期化コードの実行に時間がかかる場合があります。
このオーバーヘッドの時間調節を避けるために、プロファイル・データの収集前に、データベースのウォーム・ アップを行います。ウォーム・アップを行うには、プロファイラ・データを収集せずにアプリケーションを1回実行します。
プロファイルは、システムの全ユーザーについて行うことができ、たとえば、あるパッケージの全ユーザーを(使用中か否かに関係なく)プロファイルできます。このような場合にSYSADMIN
は、変更したPROFTAB.SQL
スクリプトを使用して次の内容を実行します。
プロファイラ表および順序を作成します。
これらの表および順序のSELECT
/INSERT
/UPDATE
権限をすべてのユーザーに付与します。
表および順序のパブリック・シノニムを定義します。
注意: 表の実際のフィールドは変更しないでください。 |
一般的な実行には、次の処理が含まれます。
実行でプロファイラ・データ収集を開始します。
プロファイラ・データおよびコード・カバレッジ・データが必要なPL/SQLコードを実行します。
プロファイラ・データ収集を停止します。その実行に対して収集したデータは、データベース表に書き込まれます。
注意: 収集したプロファイラ・データは、ユーザーの切断時に自動的に格納されません。セッションの終了時にデータを格納するには、FLUSH_DATA ファンクションまたはSTOP_PROFILER ファンクションの明示的なコールを発行する必要があります。データ収集を停止すると、収集されたデータが格納されます。 |
アプリケーションの実行時、プロファイラ・データは、実行期間中存続するメモリー・データ構造に収集されます。実行の途中でFLUSH_DATA
ファンクションをコールすると、増分データを取得し、割り当てられたプロファイラ・データ構造のメモリーを解放できます。収集されたデータをフラッシュすると、その内容が前に作成したデータベース表に格納されます。
表plsql_profiler_data
に含まれる行は、コードが生成済のソース・ユニットの各行に対応しています。行番号の値でソースの行を示します。その行が存在し、total_occur値が0より大きい値である場合、その行に関連付けられたコードが実行されています。その行が存在し、total_occur値が0である場合、その行に関連付けられたコードは実行されていません。表に行が存在しない場合、その行のコードは生成されていません。したがって、レポートには記載されません。
1つの文のソースが1行に存在する場合、その文に対して生成されるコードはその行番号に関連付けられます。(単純な宣言などの場合や、最適化を行う場合、コードは不要になります)。カバレッジ情報を取得するには、ユニットはPLSQL_OPTIMIZE_LEVEL=1
でコンパイルする必要があります。
1つの文が複数行にわたる場合、その文に対して生成されるコードは、範囲内にある行に関連付けられます。ただし、範囲内にあるすべての行がそれに関連付けられたコードを持つとはかぎりません。このような場合、行番号は連続していません。特に、複数行のSQL関連の文が1つの行に存在することがあります(通常は先頭)。これは、PL/SQLが、カーソルによって処理されたテキストをSQLエンジンに渡すためです。したがって、PL/SQLに関するかぎり、SQL文全体は分割できない1つの操作です。
複数の文が同じ行にある場合、プロファイラは各文の実行を結び付けます。行に制御フローが埋め込まれている場合、混乱が生じることがあります。たとえば、'then ...'
と'else ...'
が同じ行にある場合、'then'
が'else'
のどちらが実行されたのか判断できません。
一般的に、プロファイラおよびカバレッジ・レポートでは、1つの文が1つの行に存在する場合、解釈がより迅速に行われます。
表116-4 DBMS_PROFILERの例外
例外 | 説明 |
---|---|
|
error_versionに相当します。 |
|
"error_param"または"error_io"のいずれかに相当します。 |
ファンクションからの戻り値が0
の場合は正常終了を示し、ゼロ以外の戻り値はエラー状態を示します。発生する可能性のあるエラーは、次のとおりです。
サブプログラムは不正なパラメータでコールされました。
error_param constant binary_integer := 1;
データ・フラッシュ操作に失敗しました。プロファイラ表が作成済でアクセス可能か、および十分な領域があるかどうかをチェックしてください。
error_io constant binary_integer := 2;
パッケージとデータベースの実装に不一致があります。不適切なバージョンのDBMS_PROFILER
パッケージがインストールされ、このバージョンのプロファイラ・パッケージがそのデータベース・バージョンで動作できない場合に、このエラーが戻されます。リカバリするための唯一の方法は、適切なバージョンのパッケージをインストールすることです。
error_version constant binary_integer := -1;
表116-5 DBMS_PROFILERパッケージのサブプログラム
サブプログラム | 説明 |
---|---|
|
ユーザーのセッションで収集されたプロファイラ・データをフラッシュします。 |
|
このAPIのバージョンを取得します。 |
|
このバージョンの |
PAUSE_PROFILERファンクションおよびプロシージャ |
プロファイラ・データ収集を一時停止します。 |
RESUME_PROFILERファンクションおよびプロシージャ |
プロファイラ・データ収集を再開します。 |
START_PROFILERファンクションおよびプロシージャ |
ユーザーのセッションでプロファイラ・データ収集を開始します。 |
|
ユーザーのセッションでプロファイラ・データ収集を停止します。 |
このファンクションは、ユーザーのセッションで収集されたプロファイラ・データをフラッシュします。データは、以前から存在しているデータベース表にフラッシュされます。
注意: PROFTAB .SQL スクリプトを使用して、プロファイラ・データを継続的に格納するための表や他のデータ構造を作成します。 |
このファンクションは、ユーザーのセッションでプロファイラ・データ収集を開始します。
START_PROFILER
ファンクションの2つのフォームがオーバーロードされており、1つは実行を開始した実行番号およびコール結果を戻します。もう1つは実行番号を戻しません。最初のフォームは、プロファイラを制御するGUIベースのツールで使用することを目的としています。
構文
DBMS_PROFILER.START_PROFILER( run_comment IN VARCHAR2 := sysdate, run_comment1 IN VARCHAR2 :='', run_number OUT BINARY_INTEGER) RETURN BINARY_INTEGER; DBMS_PROFILER.START_PROFILER( run_comment IN VARCHAR2 := sysdate, run_comment1 IN VARCHAR2 :='') RETURN BINARY_INTEGER; DBMS_PROFILER.START_PROFILER( run_comment IN VARCHAR2 := sysdate, run_comment1 IN VARCHAR2 :='', run_number OUT BINARY_INTEGER); DBMS_PROFILER.START_PROFILER( run_comment IN VARCHAR2 := sysdate, run_comment1 IN VARCHAR2 :='');