|
|
|
この章では、作成したアプリケーションのパフォーマンスを改善するための提案について説明します。この章は、次の項から構成されます。
詳細へ進む前に、3.2項の紹介情報を読んでください。3.3項のパフォーマンス測定に関する資料も参考になります。
提案は、内容に従って次の順序でグループ化されています。
パフォーマンスを改善するための設定をする前に、特定の目的とその達成に関わることについて明確な見解があれば役立ちます。
改善する領域、およびその領域のパフォーマンスを識別または測定する方法を正確に知る必要があります。
さらに、パフォーマンスを改善するには、今日のコンピューティング環境における多くの相互関係や依存性、関連コスト、およびある領域のパフォーマンスを改善する上で生じるトレードオフについて理解する必要があります。
Forms DeveloperおよびReports Developerは、設計時および実行時に使用します。設計時は、プログラマがアプリケーションを作成するときであって、パフォーマンスの点では通常重要ではありません。ランタイムは、日々のビジネス環境で複数のエンド・ユーザーがアプリケーションを実行する時のことであって、常に最も重要になります。したがって、この章ではこれ以降ランタイム環境におけるパフォーマンスについて説明します。
アプリケーションのパフォーマンスの見方はいろいろあります。アプリケーションのストレージ要件、コーディング効率、ネットワーク負荷およびサーバー利用などが領域の一部です。どの状況も異なっており、各サイトおよび部署には独自の優先順位があり、どのパフォーマンス領域が最も重要であるかについての独自の見解があります。さらに、これらの領域における「良い」パフォーマンスおよび「悪い」パフォーマンスは相対的なものです。絶対的な基準はありません。
通常、最も認識しやすい領域はエンド・ユーザーへの応答時間(つまり、アプリケーションを使用している人が選択や入力を行った後で待つ時間)に関するパフォーマンスです。この場合も、絶対的な基準はありません。実際の応答時間がどうであれ、ユーザーはどのような物に慣れているか、何を期待しているか、に主に依存する見解を持っています。実際の数値は非現実的な値です。エンド・ユーザーが応答時間に不満である場合、この領域は確実に改善の対象となります。
アプリケーションはそれだけでは実行できません。クライアント/サーバー環境において、アプリケーションは基本となるハードウェアとオペレーティング・システムの2つと、ハードウェアとソフトウェアのネットワーク通信に依存しています。3層環境では、状況はより複雑になります。さらに、アプリケーションは1つ以上のデータベース・サーバーと対話し、実行時には他のソフトウェア・コンポーネントをコールすることもあります。
また、アプリケーションは多くの場合これらのハードウェアおよびソフトウェア・リソースを他のアプリケーションと共有しています。この共有のため、単体では効率的なアプリケーションが、他の非効率的なアプリケーションによって悪影響を受ける可能性があります。
したがって、アプリケーションのパフォーマンスは単なるそれ自体の設計や利用の結果ではなく、多くの異なるコンポーネントや要素の対話を組み合せた非常に複雑な結果です。
パフォーマンスの改善の中には直接的な効果があるものがあります。たとえば、アプリケーションの無駄なコードを削除する場合などです。
ただし、他の改善はそれほど明快ではありません。たとえば、あるアプリケーションのネットワーク優先順位を必要性によって高くすると、他の優先順位が相対的に下がります。また別の例として、あるタイプのアプリケーションへのアクセス時間を改善するためにデータベースを再構築した場合、実際には他の重要なアプリケーションへのアクセス時間に影響を与えていることがあります。
1つのアプリケーションのレベルでの典型的なトレードオフは、領域と速度です。いくつかのコンポーネントをロード対象からはずすことで、主なストレージ要件を減らすことはできますが、これは(ロード対象からはずれたコンポーネントを必要なときにロードしなければならないため)アプリケーションの応答時間に影響を与える可能性があります。一方、ロード操作を起動段階へ移動することで前述の応答時間は改善されますが、最初の起動時のオーバーヘッドの増加が犠牲になります。
特定の改善作業を決定する前に、密接な関係をより明確に理解し、優先順位に従って選択をすると役に立ちます。
アプリケーションのパフォーマンスが適切かどうかの見分け方
応答時間の場合、エンド・ユーザーの意見が最も重要です。他の領域については、より具体的なデータ、場合によっては非常に多くのデータが必要です。
ビルトイン・パッケージのOra_Profは、Forms DeveloperおよびReports Developerの両方に付属しています。このツールを使用すると、アプリケーションのPL/SQLを検証し、コードのある一部分を実行するのに必要な時間を調べることができます。
次の製品固有の測定ツールも利用できます。
ランタイム・オプションSTATISTICS=YES
を設定することで、Formsアプリケーションの一般情報を得ることができます。
Form BuilderのPerformance Event Collection Services(PECS)を使用して、アプリケーションのランタイム動作についての詳細情報を収集することができます。
ランタイム・オプションPECS=ON
を指定して、PECSデータ収集をアクティブ化します。
PECSの最も簡単な用途は、アプリケーション全体の統計を集めることです。これには(ランタイム・オプションでPECSをアクティブ化するのみで)既存のアプリケーションへの変更は必要ありません。
PECSはアプリケーションの特定の領域に絞ることもできます。PECSは、コードに挿入して詳細に検証するセクション、イベントまたはクラスを識別できる、多数のビルトインを提供します。
データの収集が完了すると、PECS Assistantを使用して参照し分析することができます。Assistantはさまざまなタイプのレポートを生成し、経過時間、CPU時間、イベントまたはオカレンス、PL/SQLコードの利用状況などが参照できます。アプリケーションのランタイム動作を分析することで、改善の可能性がある領域を見つけることができます。たとえば、コードの一部が他と比べ実行時間が非常に長い場合、より詳しい調査の対象となります。
Report Builderには次の2つの測定ツールがあります。Reportsプロファイル・オプションとReportsトレース・オプションです。
Reportsプロファイル・オプションを設定すると、レポートがどこにどれだけの処理時間を費やしたかを示すログ・ファイルを生成します。これはパフォーマンスのボトルネックの識別に役立ちます。
プロファイル・オプションを設定するには、PROFILE=<filename>
を指定します。ここで、<ファイル名>
は必要なログ・ファイルの名前です。プロファイルはレポート・パラメータまたはコマンド・ライン引数のどちらにもなります。
サンプルのレポートからの典型的なプロファイル出力を次に示します。
合計経過時間: |
29.00秒 |
Reports時間: |
24.00秒(全体の82.75%) |
Oracle時間: |
5.00秒(全体の17.24%) |
UPI: |
1.00秒 |
SQL: |
4.00秒 |
このプロファイルから、レポートの実行時間(合計経過時間)、フェッチしたデータをフォーマットするのに費やした時間(Reports時間)、およびデータの取出しを待つのに費やした時間(Oracle時間)を見ることができます。UPI時間は、データベース接続およびSQLの解析と実行に費やす時間のことです。SQL時間は、データベース・サーバーがデータのフェッチに費やした時間と、SRW.DO_SQL()
文(アプリケーションに含まれるDML文とDDL文)の実行に費やした時間のことです。
この例でプロファイルは、ほとんどの時間が問合せやフェッチではなくデータのレイアウトに費やされていることを示しています。
Reportsトレース・オプションは、レポートの実行時にレポートが行う一連のステップを示すファイルを生成します。トレース・オプションは、ファイルにすべてのイベントのログを取るか、またはステップのサブセットのみをログに残すように設定することができます。トレース・ファイルは、パフォーマンスのチューニングだけでなく、何がいつ実行されたかを知る上でも役立つ多くの情報を提供します。
トレース・オプションは、メイン・メニュー(「ツール」→「トレース」を選択)、コマンド・ライン引数TRACEFILE
(トレース情報のファイル名)、TRACEMODE
またはTRACEOPTS
(トレースが必要なイベント・タイプのリスト)のどちらからでも設定できます。
データベース・サーバーおよびネットワーク・システムは通常、これらの領域のパフォーマンス情報を得るために使用する測定および分析ツールを提供します。
たとえば、SQLをチューニングするのに非常に貴重な支援ツールは、Oracleデータベース・サーバーが備えるSQLトレース機能です。SQLトレースによって、データベースに送られるSQLだけでなく、文のデータの解析、実行およびフェッチに要する時間が参照可能になります。トレース・ファイルの生成が完了したら、TKPROFユーティリティを使用してExplain Planを生成します。これはOracle Optimizerが使用する実行プランのマップです。Explain Planは、たとえば表の完全スキャンを使用した場所を示し、(パフォーマンス・ヒットによっては)アプリケーションがインデックスを使用すれば利点があることを提案します。Explain Planの詳細は、『Oracle SQL言語リファレンス・マニュアル』を参照してください。
アプリケーションが使用しているサーバーやネットワーク・システムが提供する測定ツールや分析ツールで確認するだけでなく、これらの領域の管理者にも問い合せてください。既存の環境でアプリケーションのパフォーマンスを改善するための方法を直接支援、または提案できるかもしれません。
次のパフォーマンス改善ガイドラインは、Forms DeveloperおよびReports Developer全般(コンポーネントBuilderすべて)と、実行環境(クライアント/サーバーおよび3層)の両方に適用できます。
一般的なガイドラインでは次の領域について説明します。
パフォーマンスを改善する最も簡単な方法は、ハードウェアまたはソフトウェア、あるいはその両方をアップグレードすることです。アップグレードに関わる作業はありますが、新しいコンポーネントによって得られるパフォーマンスの改善は通常その作業に値するものです。
Oracleソフトウェアの各後継リリースでは、パフォーマンスが向上し、前のリリースの機能も拡張されます。改善はさまざまなカテゴリにわたって見られ、当然ながらリリースごとに変化します。ただし多くの場合、新しいリリースでは新機能だけでなく、何らかのパフォーマンスの向上として新しいチューニング支援や自動パフォーマンス改善などの機能も提供します。
たとえばリリース1.6では、リリース1.5を改良し、複数のアプリケーション・サーバーを効率的に使用することが可能になるロード・バランサーを提供しています。リリース2では、戻りレコード表機能を提供します。この機能では、ストアド・プロシージャへ1度変更を渡すことで、ネットワーク・トリップを防ぎながら複数の表へ順番に変更を配布することができます。また別の例として、リリース6は、データベース・サーバーへのインタフェースとなるOCI言語をより効率的に使用する変更された内部コードを含み、顧客のアクションを必要としない改善を提供します。
最新のより効率的なリリースへのアップグレードを考慮 してください。
当然ながらForms DeveloperおよびReports Developerは、他のソフトウェア、特にOracleデータベース・サーバーおよびPL/SQL言語コンポーネントと同時に実行されます。関連するコンポーネントのパフォーマンスの向上は、多くの場合アプリケーションのパフォーマンスの向上に直結します。これらの領域のチューニング機能は、アプリケーションのパフォーマンスを改善するより多くの機会を提供します。
関連ソフトウェアの最新のリリースを使用することで、常により良いパフォーマンスを得ることができます。たとえばOracle8データベース・サーバーは、Oracle7と比べて随所でパフォーマンスが改善されています。たとえば、表と索引の分割、並列処理の向上、整合性の検証の譲歩などです。
したがって、データベース・サーバーや他の関連ソフトウェアの選択を制御したり、それに影響を与えたりすることができる範囲で、より最新の効率的なレベルにアップグレードすることを考慮してください。
ハードウェア・システムの基本となる容量または速度、あるいはその両方を増加することは、パフォーマンスを改善する明白なアプローチです。このアプローチには、デスクトップおよびサーバー・マシンだけでなくその間のネットワーク接続も含まれます。
データベースへのアクセスは、典型的なForms DeveloperおよびReports Developerアプリケーションでの主要アクティビティです。データを効率的に読み書きできることが、パフォーマンス全体へ重要な影響を与えます。
Forms DeveloperおよびReports Developerでは、Oracleデータベース・サーバーの配列処理機能を使用することができます。これは、一度に1つずつではなくバッチでデータベースからレコードをフェッチすることを可能にし、結果的にデータベースのコールを大幅に減らすことになります。配列処理のマイナス面は、実行プラットフォームで返されたレコードの配列を格納するためにより多くの領域が必要となる点です。
本番環境でネットワーク上の負荷が主なボトルネックとなる場合は、Developer製品のランタイムARRAYSIZE
パラメータをランタイム環境と同じくらい大きい値に設定します。
理想的には、アプリケーションには冗長な問合せ(不要なデータを返す問合せ)があってはいけません。パフォーマンスが明らかに低下するからです。ただし、アプリケーションが異なるユーザーに異なる書式を作成する必要がある場合、および異なる問合せ文を使用する必要がある場合には、この状況が発生します。2つの異なるアプリケーションを開発することで問題が解決するのは明らかですが、メンテナンスを容易にするためには1つのアプリケーションのみであることが望ましいと言えます。
たとえば、レポートでSRW.SET_MAXROW()
プロシージャを使用する冗長な問合せを使用しないようにすることができます。Before Reportトリガーの次のコードは、ユーザー・パラメータによってQuery_EmpまたはQuery_Deptのいずれかを使用不可にします。
IF :Parameter_1 = 'A' then SRW.SET_MAXROW('Query_Emp',0); ELSE SRW.SET_MAXROW('Query_Dept',0); END IF;
SRW.SET_MAXROW()
を使用する場合は、いくつか気を付ける必要がある点があります。
SRW.SET_MAXROW()
を使用する意味がある場所は、Before Reportトリガー内(問合せを解析した後)のみです。SRW.SET_MAXROW()
がこの時点の後でコールされた場合、パッケージされている例外処理SRW.MAXROW_UNSET
が発生してしまいます。
アプリケーションがデータベースに多くの時間を費やすことがわかっている場合、データの構造とその利用方法を見直すことに利点がある場合がよくあります。Forms DeveloperおよびReports Developerは、設定に基づいたロジック向けに最適化されている非手続き型ツールであり、スキーマ設計が不適切である場合、きわめて悪い影響を及ぼす可能性があります。たとえば、何度も正規化したデータ・モデルは不要な結合や問合せを回避できますが、適切なインデックスがなければ表の完全スキャンを無駄に増やすことになります。
アプリケーションの固有の特徴から最も効率的なデータ・モデルが決定します。問合せ駆動型アプリケーションは表を非正規化することで利点があります。正規化した表は更新や挿入を頻繁に行うアプリケーションに適しています。
データベースおよびサーバーの効率的な設計と操作は明らかにクライアント・アプリケーションに利点をもたらします。ただし、データベースの作成と管理は大きな問題であり、通常はアプリケーション開発者が関わる領域ではないため、データベース・パフォーマンスについてはここでは紹介するのみとします。詳細は、『Oracle Serverチューニング』マニュアルを参照してください。マニュアル、およびSQLトレースやTKPROFユーティリティなどのサーバー・ツールを使用して、データ・モデルの改善できる場所を調べることができます。
その領域が直接制御できる範囲外だとしても、データベース・サーバーの管理者に、特定のパフォーマンス問題を処理することが相互の利益になるかどうか問い合せてください。
Forms DeveloperおよびReports Developerは、SQLを使用してデータベースと対話し、データを取り出します。アプリケーションをチューニングする場合、十分なSQLの作業知識があり、データベースがSQL文を実行する方法を理解していると役に立ちます。
アプリケーションの非効率的なSQLは、パフォーマンスに甚大な影響を与える可能性があります。これは特にアプリケーションに多くの問合せがある場合に当てはまります。
Oracleデータベース・サーバーには2つのSQLオプティマイザがあります。コスト・ベースとルール・ベースのオプティマイザです。コスト・ベースのオプティマイザを使用すると、SQLの複雑なチューニングに関わることなく大量の自動最適化が行えます。さらに、詳細にチューニングするためのヒントが提供されています。ルール・ベース(帰納的)オプティマイザを使用して、SQLを詳細にチューニングして最適化のレベル以上まで達することも可能ですが、実際には新たな作業とSQL処理の理解が必要となります。
ほとんどのアプリケーションの場合、コスト・ベースのオプティマイザで満足のいく最適化レベルが得られます。実際、チューニングをしていないコスト・ベースの最適化が、手動でチューニングしたルール・ベースの最適化より優れていることもよくあります。ただし、データの広がりおよびオプティマイザを制御するルールを理解している開発者で、さらに高いレベルの効率を目指す場合は、ルール・ベース方法を試すこともできます。
いずれにしても、どちらかのオプティマイザを選択することが重要です。次のいずれかを選択します。
ANALYZE
を実行するか、またはinit.ora
パラメータを設定して)アクティブ化するか、あるいは
アプリケーション内で計算を実行する場合、一般的な目安としてできるだけ多くの計算を問合せSQL内で実行した方がパフォーマンスが向上します。SQLに計算が含まれている場合、データはデータベースによって計算されてから返されますが、アプリケーションが計算する場合は返されたデータをキャッシュしてから計算を行います。Oracle 7.1以降では、問合せ選択リストにサーバー・ストアド・ユーザー定義PL/SQLファンクション・コールを含めることができます。これは計算されたデータがデータベースからの結果の一部として返されるため、それ以上計算する必要がなく、(たとえば、計算列内で)ローカルPL/SQLファンクションを使用するよりも効率的です。
Oracle 8では、メソッドのコールで、引数の受渡しを簡素化し高速にするSELFパラメータを使用することができます。
アプリケーションで明示的なカーソルを宣言し使用することで、データベースの問合せを完全に制御することができます。ただし、このようなカーソルが必要なことはほとんどありません(Forms DeveloperおよびReports Developerは、必要なカーソルをすべて暗黙的に作成し、管理します)。明示的なカーソルはネットワーク通信量も増加させるため、ほとんどのアプリケーションでは使用を避けなければなりません。
グループ・フィルタはReportsおよびGraphicsコンポーネントで利用することができます。
グループ・フィルターは主に、取り出したレコード数を最初または最後のnレコードに制限するために使用しますが、PL/SQLフィルタ条件を作成するオプションもあります。グループ・フィルタを使用する場合も、問合せはデータベースに渡され、すべてのデータがアプリケーションに返されますが、ここでフィルタを行います。このため、アプリケーションは最初の5レコードのみを表示しますが、返された結果には問合せによって返されたレコードすべてが含まれています。
このため、できるだけグループ・フィルタを問合せのWHERE節に組み込むことがより効率的です。こうしてデータベースが返すデータを制限します。
Forms DeveloperおよびReports Developerは、複数のコンポーネントを使用するアプリケーションを作成する機能を提供します。たとえば、データをフェッチしてFormsで操作し、FormsからReportsに出力を作成するようコールすることができます。ReportもGraphicsをコールして出力を視覚的に表示することができます。
各コンポーネントはデータを再問合せすることができるため、Formsはデータを保持するためにレコード・グループを作成し、次にパラメータとしてReportsへ渡し、Repotsも同様にGraphicsへ渡すとより効率的です(このテクニックは問合せの分割とも言います)。このテクニックを使用する場合、データの問合せは一度のみ行われます。
あるコンポーネントが別のコンポーネントをコールし、コールされたコンポーネントがまだメモリーにない場合、ロードするのにいくらか時間がかかります。このような必要に応じての呼出しはメモリーをより効率的に使用できますが、エンド・ユーザーにとってはかなりの待ち時間が発生します。
(コール側コンポーネントが)コールされるコンポーネントを先にロードしておくことで待ち時間を減らすことができます。これによって起動時間は長くなりますが(また、メモリーの利用効率も悪くなりますが)、通常、起動時の待ち時間は処理中の待ち時間よりも気にならないものです。
(このテクニックはFormsがReportsをコールする場合の方がReportsがGraphicsをコールする場合よりも有効です)。
この章のここまでの一般的な提案はすべてFormsアプリケーションにも適用されます。さらに、次の項目について考慮します。
配列処理に関する一般的な数値やトレードオフについてはすでに記述しました。Formでは、問合せの設定はブロック・プロパティ「問合せ配列サイズ」で制御します。更新/挿入/削除については配列処理設定はブロック・プロパティ「DML配列サイズ」で制御します。
可能な限り、データ・ブロックはストアド・プロシージャに基づかせます。
ストアド・プロシージャは処理をサーバーに移動する最も直接的な方法です。正確に設計されていれば、ストアド・プロシージャは多くのネットワークのラウンド・トリップを取り除くこともできます。たとえば、問合せをストアド・プロシージャに基づくようにすることで、外部キーの参照および計算をPost-Queryトリガー内ではなくサーバー上で行うことができます。このようなトリガーは通常、1行あたり少なくとも1ラウンド・トリップを追加するので、配列フェッチの利点がなくなります。
同様に、ストアド・プロシージャを通して更新を行うことで、監査証跡または非正規化データを新しいネットワーク・ラウンド・トリップなしに記述することができます。DMLを実行する前に必要となる妥当性チェックについても同様です。これによって、これまでPre-Update、Pre-Insert、Pre-Deleteトリガーで発生していたネットワーク・ラウンド・トリップを排除します。
2.0より前のリリースを使用している場合は、On-SelectやOn-Fetchなどのトランザクション・トリガーを記述することで、手動でストアド・プロシージャに基づくデータ・ブロックを作成することができます。リリース2.0以降を使用している場合は、ストアド・プロシージャを通してフェッチを行うことができます。
ストアド・プロシージャにはまた、問合せに関する2つのオプションもあります。1つ目のオプションはデータ・ブロックの問合せを、「Refカーソル」を返すストアド・プロシージャに基づいて作成します。もう1つのオプションは、「レコード表」を返すストアド・プロシージャです。
RefカーソルはPL/SQL構造体で、ストアド・プロシージャがカーソルをオープンし、クライアントに「ポインタ」またはカーソルへの参照を返すのを可能にします。これによってクライアントは、カーソル自体をオープンした時と同じようにカーソルからレコードをフェッチすることができます。Formsの場合は、Formsが表またはビューに直接基づくデータ・ブロックのカーソル自体をオープンした時と全く同じように、配列フェッチを使用してRefカーソルを通してレコードをフェッチします。
Refカーソルに基づくデータ・ブロックには、ビューに基づくデータ・ブロックと多くの類似点がありますが、Refカーソルには2つの主な利点があります。1つ目の利点は、ストアド・プロシージャがより優れたデータのカプセル化を提供する点です。表への直接問合せによるアクセスを拒否することで、意味のある方法(たとえば、特定の情報を作成するために特別な方法で結合するように設計された表)または効率的な方法(たとえば、インデックスが利用できるような方法での問合せ)でのみアプリケーションがデータを問い合わせることを保証できます。
2つ目の利点は、ストアド・プロシージャをより柔軟にすることができる点です。プロシージャは、カーソルのオープンで複数のSelect文のどれを実行するかをランタイム時に決定することができます。この判定はユーザーの役割または権限によって決まります。たとえば、マネージャはEmp表のすべての列を参照できますが、事務員には給与の列が空白で示されます。あるいは、異なるデータ・セット(たとえば過去のデータと現在のデータ)を1つのデータ・ブロックに表示できるようにパラメータによって判定します。PL/SQLを記述できる場合には、判定を好きなだけ複雑にすることができます。唯一の制限は、異なるSelect文のすべてが互換性のある列を返さなくてはならないことです。Select文をランタイム時に動的に構成することはできません(データベースは動的SQLを使用するRefカーソルをまだサポートしていません)。
注意: REFカーソルを使用するとQuery-by-Exampleは使用できません。
PL/SQLリリース2.3で紹介した、レコード表はデータベースの表に似ているメモリー内構造です。ストアド・プロシージャは、配列のように1行ずつ構築することができる、文字どおりあらゆるデータから成るメモリー内の表を作成します。RefカーソルはSQLでの作成方法がわかれば何でも返すことができますが、レコード表はPL/SQLでの作成方法がわかれば何でも返すことができます。サーバー側での参照や計算の実行ができるだけでなく、返されたレコードのどのレコードを含めるか、または除くかについて複雑な判定を行うこともできます。
PL/SQLでは比較的簡単にできて、SQLではかなり困難なことの例としては、各部署内で給与が上位5番目までに入る従業員を返す場合などがあります(SQLでこれが困難なのは、上位5番目の給与と同じ給与の人が複数いる可能性があるからです。PL/SQLでは、これは比較的簡単なループです)。
Formsの問合せにコールされた場合、プロシージャはサーバ側でレコード表を作成します。次に、ネットワーク・パケット・サイズで許されるできるだけ少ない物理ネットワーク・ラウンド・トリップを使用して、クライアントに結果全体を一度に返します。表の各レコードはFormsブロックの行になります。これはサーバーのリソースを解放し、ネットワーク帯域幅を非常に効率的に使用しますが、クライアントのリソースを犠牲にし、おそらく不要なレコードのネットワーク通信量を浪費します。
マスター/ディテール問合せに使用する場合は、レコード表テクニックが問合せのすべての詳細レコードを返す点に注意してください。したがって、このテクニックは小さ目の問合せにのみ適しています。
要約すると、レコード表は結果を判定する上では優れた柔軟性がありますが、使用には注意が必要です。
注意: REFカーソルを使用するとQuery-by-Exampleは使用できません。
リリース2.0では、ブロックでの挿入、更新および削除を行うストアド・プロシージャに返されるレコード表も使用することができます。ストアド・プロシージャは、必要な表に変更を“広げる”ことができ、データ・モデルが高度に正規化されている場合は多くのネットワーク・ラウンド・トリップを潜在的に節約することもできます。その他の用途としては、監査証跡の記述があります。そのためには、Insert、Update、Deleteの各プロシージャが必要です。
普通の表に基づくブロックの場合、Formsはレコードが挿入、更新または削除されたものなのかを判定するために各レコードの状態を自動的に保持します。コミットの際に、Formsは挿入されたレコードすべてに対するレコード表、更新されたレコードおよび削除されたレコードについてもそれぞれのレコード表を作成します。次にそれぞれのプロシージャをコールし、対応するレコード表を渡します。問合せの場合は、レコード表は“1回”で渡されます。この場合は、いずれにしてもレコードはすべてサーバーに送ってコミットする必要があるため、一度に表全体を送ることに不都合はありません。
最後に、これらのテクニックをそれぞれ好きなように組み合せることができることについて説明します。たとえば、Refカーソルを通して問合せを選択し、レコード表を通してDMLを実行することで、両方の利点を活用することができます。
デフォルトでは、Formsはフォームを暗示的に実行するか、またはデータのポスティングや問合せの一部として実行する各SQL文に別々のデータベース・カーソルを割り当てます。各カーソルの文は毎回ではなくRunformセッションで実行された最初の時だけ解析する必要があるため、この動作によって処理が向上します。
Formsでは、すべての暗示的なSQL文(問合せSELECT以外)に対して1つのカーソルを使用することで、メモリーを節約することができます。これを行うには、ランタイム・オプションOptimizeTP
をNoに設定します。ただし、通常、メモリーの節約はそれほど意味がなく、これを行った場合、Insert、Update、DeleteおよびUpdate文のSelect文は実行されるたびに解析する必要があるため、処理速度が低下します。
このため、OptimizeTP=NO
設定を使用することは避けることをお薦めします。
デフォルトでは、Formsはトリガーでフォームが明示的に実行する各SQL文ごとに別々のデータベース・カーソルを割り当てます。各カーソルの文は毎回ではなくRunformセッションで実行された最初の時だけ解析する必要があるため、この動作によって処理が向上します。
Formsでは、トリガーのすべてのSQL文に対して1つのカーソルを使用することでメモリーを節約することもできます(これを行うには、ランタイム・オプションOptimizeSQL
をNoに設定します)。ただし、通常、メモリーの節約はそれほど意味がなく、これを行った場合、SQL文は実行されるたびに解析する必要があるため、処理速度が低下します。
このため、OptimizeSQL=NO
設定を使用することは避けることをお薦めします。
大きいアプリケーションは複数の小さいフォームに分割して、必要に応じてさまざまなフォーム間をナビゲートする方が効率的な場合があります。
頻繁に使用するフォームは最初に使用した後オープンしたままにしておくことで、使用するときに毎回オープンしてクローズするよりナビゲーション時間を減らすことができます。フォームのクローズおよび再オープンは相当のオーバーヘッドにつながり、パフォーマンスを低下させます。
フォームをオープンしたままにするためには、NEW_FORMビルトインではなくOPEN_FORMビルトインを使用してナビゲートします(NEW_FORMは新しいフォームをオープンする際、前に使用していたフォームをクローズします)。
フェッチ・サイズが大きいほど、レコード・グループを得るために必要なフェッチ回数が減ります。アプリケーションでレコード・グループを使用する場合(または、ランタイム時にレコード・グループを作成する場合)、「レコード・グループのフェッチ・サイズ」プロパティを使用してこのサイズを設定します。
Oracle8サーバーを使用している場合、LONGやLONG RAWではなくLOB(大きいオブジェクト)データ型を使用する方がより効率的です。
各グローバル変数は255バイト使用します。アプリケーションで多くのグローバル変数を作成する場合、変数は不要になった時点で削除することを考慮してください(削除には、Eraseビルトインを使用します)。
次の提案を採用すると、Microsoft Windows上で実行される非常に大きいフォームのリソース使用が改善される可能性があります(これらの提案は、標準設計の場合では使用を控え、リソース使用が問題になっている場合にのみ使用してください)。
ユーザーがデータを更新すると、Formsによってレコードがロックされ、データベースへのラウンド・トリップが実行されます。
1人のユーザーのみがデータを更新している場合は、ロックは必要ありません。ロックを解除するには、Formの「隔離モード」プロパティを「逐次可能」に、ブロック・プロパティ「ロック・モード」を「延期」に設定します。
ただし、Formsのロックの抑止はデータの同時使用がないことが確実である場合にのみ行うようにしてください。
この章のここまでの一般的な提案はすべてReportsアプリケーションにも適用されます。さらに、次の項目について考慮します。
データベースからデータを取り出した後、Reportsはユーザーが作成したレイアウト・モデルに従って出力をフォーマットする必要があります。レイアウトの生成に要する時間は要素数に依存しますが、ほとんどの時間は他のオブジェクトによるオブジェクトの上書きを防ぐことと、フォーマット・トリガー内の計算やファンクションの実行などに使用されています。これらの2つの領域の効率を改善すれば、相当の利点があります。
デフォルトのレイアウトを作成するときに、Reportsはレポートを実行した場合に上書きされないように保護するため、事実上各オブジェクトの周囲に枠を挿入します。実行時に、すべてのレイアウト・オブジェクト(枠、フィールド、ボイラープレートなど)は、上書きされる可能性がないかを検証されます。状況によっては(たとえば、ボイラープレート・テキスト列見出し)、オブジェクトが上書きされる危険性はないことが明らかであれば、すぐに周囲の枠を削除することができます。これによって、Reportsがフォーマットする必要があるオブジェクト数が減り、パフォーマンスが改善されます。
同様に、オブジェクトのサイズ(水平および垂直方向のいずれかまたは両方を拡大、縮小する変数)が未定義の場合、Reportsはオブジェクトとその周囲をフォーマットする前にオブジェクトのサイズのインスタンスを決定する必要があるため、新たに別の処理が必要になります。できるだけこのサイズ指定を固定すると、オブジェクト間のサイズおよび位置関係が確定されるため、別の処理を排除できます。
一般的には、フォーマット・トリガーを使用するよりも、宣言的なフォーマット・コマンドを使用する方が好ましいといえます。ただし、フォーマット・トリガーは実行時に変更を行うのには便利です。具体的には、
フォーマット・トリガーを使用する際には必ず慎重に扱い、トリガーは出力媒体上の関連するオブジェクトのすべてのインスタンスだけでなく、実行時にオブジェクトをフォーマットするときにも発生することに注意してください。
上で説明したこれらの2つの目的は同じように見えますが、次の例を考えてみてください。ある表レポートは、縦に伸ばすことが可能な1つの繰返し枠を含み、ページ保護が設定されています。このレポートがフォーマットされるとき、最初のページの最下段にあと1行余白があります。Reportsは次の繰返し枠のインスタンスのフォーマットを開始し、関連するフォーマット・トリガーを発生させます。繰返し枠の中のオブジェクトの1つが拡張されていることがわかると、この繰返し枠のインスタンスは次のページへ移動されるため、繰返し枠のフォーマット・トリガーが再度発生します。このため、繰返し枠は(2ページ目の1行目に)一度しか表示されないにもかかわらず、フォーマット・トリガーは2度発生しています。このフォーマット・トリガーにINSERT文が含まれていた場合、同じデータの行が2行挿入されてしまいます。
また、フォーマット・トリガーはトリガーの発生頻度を最少にするために、オブジェクト/枠の階層で最高のレベルに位置づける必要があります。たとえば、枠内に4つのフィールドがある場合、フィールド・レベルのフォーマット・トリガーは4回発生しますが、枠レベルのフォーマット・トリガーが発生する必要があるのは一度のみです。
PL/SQLがフォーマット・トリガー内になければならない場合、できるだけ発生頻度の少ないオブジェクトのトリガーに含めます。たとえば、PL/SQLをフィールドではなく枠のフォーマット・トリガーに含めることで、レポートの実行をより高速にすることができます。フォーマット・トリガーのPL/SQLはそのオブジェクトのインスタンスごとに実行されます。オブジェクトの発生頻度が少ないほど、PL/SQLの実行回数が少なくなり、レポートの実行が高速になります。
特定のオブジェクトに対してフォーマット・トリガーが何回発生するかはわからないため、フォーマット・トリガーでは計算の実行や、DMLの使用を行わないでください。
フィールドの表示属性を動的に変更する必要がある場合、すべての属性の変更をSRW.ATTR()
を1回コールして設定するか、あるいはSRW.SET
ビルトインを数回コールし、各コールで各属性を設定することができます。後者のテクニックを使用するとコードが読みやすくなりますが、ランタイム効率は特に多くの属性を設定しなければならない場合は、SRT.ATTR()
を1回呼び出す方が効率的です。
ほとんどの操作と同じように、複数の表を含むデータ・モデルを作成する方法は何通りもあります。たとえば、部署と従業員の表の結合という標準的な場合を考えてみます。つまり、要件は企業の各部署の従業員すべてをリストすることです。Reports Developerでは、プログラマは1つの問合せを作成することも、2つの問合せを作成してその問合せ間にマスター/ディテール・リレーションを使用することもできます。
アプリケーション側では、データ・モデルの設計の際に、多数の簡単な(単一表の)問合せではなく、少数の大きい(複数表の)問合せを使用して、実際の問合せ数を最小にするのがより好ましいといえます。Reports Developerでは、問合せが発行されるたびに解析、結合が行われ、カーソルが実行されます。このため、1つの問合せが、複数ではなく1つのカーソルに必要なデータすべてを返すことができます。また、マスター/ディテール問合せでは、ディテール問合せは各マスター・レコードが取り出されるたびに再解析され、再結合され、再実行される点に注意してください。この例では、レポートで2つの問合せをマージして、マスター/ディテール効果を作成するためにブレーク・グループを使用するとより効率的です。
ただし、問合せが大きくなり、より複雑になるとメンテナンスが困難になる点に気を付けてください。各サイトはパフォーマンスとメンテナンス要件のバランスを取る方法を決める必要があります。
レポートを効率的に実行するように設計した場合、特定のランタイム引数を設定することでレポートのパフォーマンス全体をさらに改善することができます。
ARAYSIZE
およびRUNDEBUG
設定については前に説明しました。
レポートのパラメータ・フォームまたはオンライン・プレビューが必要ない場合は、PARAMFORM
およびBATCH
システム・パラメータを適切に設定することで、これらのファンクションを無視することができます。
アプリケーションを通常の本番環境で使用している場合は、デバッグ・モードで実行されていないことを確認してください。
アプリケーションをデバッグ・モードで実行すると、情報が収集され、余分な内部操作が実行されます。アプリケーションのデバッグが終了したら、これらの操作はもはや不要で、パフォーマンスを低下させるのみです。
Reportsでは、デバッグ・モードはランタイム・パラメータRUNDEBUG
によって制御されます。このパラメータを「No」に設定します。
レイアウト・オブジェクト(たとえば、枠および繰返し枠)の枠と塗りパターンを透明にします。
透明なオブジェクトは、PostScriptファイルで作成する必要はありません。結果として、オブジェクトが透明の場合は処理が速くなります。
非グラフィック・レイアウト・オブジェクト(たとえば、ボイラープレート・テキストやテキスト付きフィールド)を固定サイズにします。つまり、「固定」の「水平拡張度」および「垂直拡張度」です。特に、繰返し枠とその内容を固定するとパフォーマンスが改善されます。
サイズ可変の非グラフィック・オブジェクトは、Report Builderがフォーマットする前にサイズを決定する必要があるため、余分な処理が必要になります。サイズが固定の非グラフィック・オブジェクトは、サイズがすでにわかっているためこの処理が不要です。
グラフィック・レイアウト・オブジェクト(たとえば、イメージおよびOracle Graphicsオブジェクト)を可変サイズにします。つまり、「可変」な「水平拡張度」および「垂直拡張度」です。
固定サイズのグラフィック・オブジェクトは通常、オブジェクト内に内容がおさまるようにスケール変更する必要があります。オブジェクトの内容をスケール変更するには別の処理が必要です。オブジェクトが可変サイズの場合、内容に合わせて伸縮できるため、スケール変更は必要ありません。
サイズを減らすイメージ・オブジェクトの「イメージ解像度の削減」を指定します(このオプションは、「書式」メニューの描画オプションにあります)。
イメージのサイズを減らす場合は、大きいサイズのときと比べて表示に必要な情報が少なくなります。「イメージ解像度の削減」は不要な情報を削除し、イメージを格納するのに必要な領域を減らします。これは複数の色を使用する大きいイメージの場合に、特に有効です。
1行のテキストを含むフィールドを作成し、(たとえば、SUBSTR
ファンクションを使用して)指定された幅の中に内容がおさまることを確認します。
テキスト付きフィールドが1行以上に広がる場合は、Report Builderはワード・ラップ・アルゴリズムを使用して、フィールドをフォーマットする必要があります。フォーマットする行が確実に1行のみであるようにすると、ワード・ラップ・アルゴリズムの追加処理を避けることができます。
同一のフィールドまたはボイラープレート・テキスト内での異なるフォーマット属性(たとえば、フォント)の使用を最小限にします。
フィールドまたはボイラープレート・オブジェクトのテキストに異なるフォーマット属性を多く含む場合は、フォーマットに時間がかかります。
ブレーク順序プロパティは、ブレーク・グループのできるだけ少ない列で設定するようにしてください(ブレーク順序はグループの列名の左にある小さな三角形で示されます)。各ブレーク・グループには、ブレーク順序を設定するために少なくとも1列は含まれていることが必要です。
ブレーク・グループのソートが必要な場合は、SQLのORDER BY節を使用します。これにより、ブレーク順序ですでにソートされた行を返すことになり、クライアント側で行うソートの量を減らすためパフォーマンスが改善されます。
ブレーク順序設定がある各列に、Reportsは適切な問合せのORDER BY節に新しい列を追加します。ORDER BYの列が少なければ、データベース・サーバーがデータを返す前に行う必要がある作業も少なくなります。ブレーク・グループの作成は、問合せで定義されたORDER BY節を冗長にする可能性があります。このような場合、データベースで余分な処理を必要とするため、冗長なORDER BY節は削除する必要があります。
ブレーク順序列はできるだけ小さく、またデータベース列も(合計列または計算列とは逆に)できるだけ小さくします。この両方の条件は、できるだけ効率的にデータをフォーマットする前にReportsが行うローカル・キャッシングに役立ちます。明らかに、これらの条件が簡単に合致することはありませんが、それでも考慮に値します。
レポートで参照するGraphics Builderの図表がレポートと同じデータを一部またはすべて使用している場合、レポートから図表にデータを渡します。渡すデータは、Report Builderの図表のプロパティ・パレットで指定することができます。
レポートと図表が同じデータを使用する場合、データの受渡しによって必要なフェッチの回数を減らすことができます。レポートから図表へデータを渡さない場合は、データはレポートと図表によってそれぞれ1回ずつフェッチされるため、合わせて2回フェッチされます。
状況に応じて、PL/SQLかユーザー・イグジットのいずれかがパフォーマンスを改善することがあります。次に、PL/SQLとユーザー・イグジットのいずれを使用するかを決定する際に考慮する項目を示します。
PL/SQLを使用するとコードが手続き型になり、しかも移植可能なので強くお薦めします。PL/SQLは、レポート・レベルのオブジェクトを参照する場合にもパフォーマンスに利点があります。ユーザー・イグジットは、パフォーマンスは優れていても結合が必要であり、移植もできません。ユーザー・イグジットは、アクションを非常に大きいレポートで実行する必要がある場合、または大量の計算を行う場合に有効です。PL/SQLプロシージャは、アクションが各グループに対してのみの場合、あるいはレポート・レベルの場合に、より有効になります。また、PL/SQLですべて行えるわけではありません。外部装置の制御のようなアクションはCプログラムで作成する必要があります。
注意: パフォーマンスの改善が見られない場合や、ユーザー・イグジットを使用する理由が特にない場合は、簡単で移植可能なPL/SQLを使用してください。
DML文にパラメータを渡すのでなければ、DMLにはPL/SQLを使用します。
SRW.DO_SQL()
は、SRW.DO_SQL()
への各コールの際にコマンドの解析、結合および(通常の問合せと同じように)新規カーソルのオープンを必要とするため、使用はできるだけ控えてください。ただし問合せとは異なり、この操作はオブジェクトがSRW.DO_SQL()
を発生させるたびに行われます。たとえば、PL/SQLファンクションがSRW.DO_SQL()
を呼び出し、ファンクションが常駐するグループによって100個のレコードが返された場合、解析/結合/カーソルの作成の操作は100回発生します。このためSRW.DO_SQL()
は、通常のSQL内で行われない操作にのみ使用し、できるだけ実行回数が少ないところ(たとえば、レポートにつき1回のみ発生するトリガー)で使用することをお薦めします。
PL/SQL内でDML文を記述すると、同じ文を含むSRW.DO_SQL
をコールするよりも高速になります。DML文にSRW.DO_SQL
を使用するのは、DML文を作成するのに結合パラメータを連結することができるからです。たとえば、ランタイム・パラメータ・フォームで入力したパラメータで決定した名前の表をSRW.DO_SQL
で作成することができます。
SRW.DO_SQL ('CREATE TABLE' || :tname || '(ACOUNT NUMBER NOT NULL PRIMARY KEY, COMP NUMBER (10,2))');
使用方法: DMLにはOracle 7.1以降に付属のdbms_sqlパッケージを使用することもできます。詳細は、Oracleデータベース・サーバーのマニュアルを参照してください。
PL/SQLコードはローカル(オブジェクト・ナビゲータのレポートのプログラム単位ノード)、またはサーバーのPL/SQLライブラリに格納することもできます。
条件によって、ローカルPL/SQLは外部のPL/SQLにあるプロシージャやファンクションを参照するよりも高速に実行できる場合があります。ただし、ローカルPL/SQLが自分の環境で高速に実行できるとしても、ライブラリ・メソッド(たとえば、多くのアプリケーション間におけるコードの共有)の利点を損なうことを考慮してください。
1回のコールで複数の属性を指定して、SRW.SET_ATTR
setattr>参照のコール回数を最小限にします。各属性ごとに別々にコールするのではなく、1回のSRW.SET_ATTRのコールで複数の属性を指定することができます。
理由: SRW.SET_ATTR
の呼出し回数が少ないほど、PL/SQLを高速に実行できます。
配列処理の値についてはすでに記述しました。
Report BuilderのARRAYSIZE
実行引数(たとえばARRAYSIZE=10
)については、できるだけ大きい値を入力します。配列サイズは行数ではなくキロバイトで指定します。ARRAYSIZE
は、Report Builderがレポート実行時の問合せごとに使用可能なメモリーのキロバイト数を表します。Report Builderは、1レコードずつではなく、複数のレコードをバッチでフェッチするOracleの配列処理を使用します。結果として、バッチ処理でフェッチするデータの量を制御することができます。
Report BuilderのLONGCHUNK
実行引数(たとえば、LONGCHUNK=10
)については、できるだけ大きい値を入力します。使用するマシンの推奨値については、使用しているオペレーティング・システムのOracleインストール情報を参照してください。LONGCHUNK
は、Report BuilderがLONG値を取り出す増分のサイズを規定します。LONGCHUNK
のサイズはキロバイトで指定します。
LONGCHUNK
にできるだけ大きいサイズを指定することで、Report BuilderがLONG値を取り出す増分の回数を減らすことができます。
PostScriptに出力する場合は、COPIES=1
と指定します。
PostScriptレポートに対して1より大きい値がCOPIES
に設定されている場合、Report Builderは情報を整理するためにテンポラリ・ストレージにページを保存する必要があります。これによってReport Builderが使用するテンポラリ・ディスク領域の量が相当増え、ファイルへの書込みによってパフォーマンスを低下させる可能性があります。
Report Builderには、合計ページ数、レポート・マージンまたはヘッダー・ページの総数を表示する機能があります。これは非常に便利な機能ですが、1ページ目を表示する前にレポート全体を処理する必要があります。
プレビューアまたはライブ・プレビューアのレポートを設計する際に「事前フェッチ」操作を避けることで、レポートの1ページ目を高速に表示することができます。
次の項目の場合は、参照される時に依存するデータより先に事前にフェッチすることになります。
ページ総数フィールド・ソースを使用する場合、Report Builderはページ総数を調べるためにすべてのページをテンポラリ・ストレージに保存する必要があります。これによってReport Builderが使用するテンポラリ・ディスク領域の量が相当増え、ファイルへの書込みによってパフォーマンスを低下させる可能性があります。
クロス積グループも事前フェッチを発生させます。クロス積グループのデータをクロス表にするために、Report Builderはデータすべてを先にフェッチする必要があります。これらの項目は実際にパフォーマンスが低下することに注意してください。プレビューアまたはライブ・プレビューアは遅くなりますが、ファイルや別の宛先に書き込む際のパフォーマンスには影響しません。
注意: 列は表示されていなくても事前フェッチを発生させます。たとえば、総計はレポート出力には表示されませんが、レポートには存在するため、Report Builderが計算する時に事前フェッチが発生します。
パフォーマンスを向上させるためにドキュメントをファイルに格納します。セキュリティのためドキュメントはレポートおよびデータベースに格納します。データベースからレポートをオープンしたりデータベースにレポートを保存したりする場合、いくつかのReport Builderの表がメモリーに入れられます。したがって、表をキャッシュするのに十分なリソースがあることを確認する必要があります。
ドキュメントについては、ファイルへの書込みおよびファイルからの読込みは、データベースよりはるかに速くなります。
例外: ファイルのアクセスに混雑しているネットワークまたは遅いマシンを使用する必要がある場合、ファイルを格納したことによるパフォーマンスの改善を感じられない可能性があります。
パス変数を指定するとファイル検索およびテンポラリ・ファイルの作成/アクセスが高速になります(Report Builderは2つの環境変数REPORTSnn_PATH
およびREPORTSnn_TMP
を提供します。これらはファイルを検索する場所とテンポラリ・ファイルを保存する場所を制御します。nnはReport Builderのリリース・レベルを表します)。REPORTSnn_PATH
は、レポートによって参照されるファイルがあるパスを指定します。REPORTSnn_TMP
は、テンポラリ・ファイルのための十分な空き領域があり、応答時間が速い装置(たとえばRAMディスク)上にあるパスを指定します。
REPORTSnn_PATH
は、Report Builderがファイル(たとえば、リンク・ファイル・ボイラープレート)を検索するデフォルトのパスです。レポートによって参照されるファイルがある場所を指定することで、Report Builderがファイルを取り出すために行う必要がある検索の量を減らすことができます(レポート定義でパスをハードコードするのではなく、REPORTSnn_PATH
を指定することで、レポートの移植性も維持できます)。REPORTSnn_TMP
は、Report Builderがテンポラリ・ファイルを作成するパスです。
サーバーを使用する場合は、server-name.ora
ファイルのSOURCEDIR=
パラメータを指定します。REPORTSnn
パスを使用する前にこのディレクトリが検索されます。
複数層Reports Serverは、デスクトップ機で実行するには実用的ではない大規模な生産レポートを効率的に扱うように設計された機能です。
この機能を使用すると、タスクにより適した強力なサーバー上で複数の大きいレポートを同時に実行することができます。サーバーは必要であれば複数のReportsエンジンを起動できるため、さらに効率を高めることができます。さらに、(レポートの生成が1回のみですむように)レポート出力をネットワーク上の複数のReportsユーザーが利用可能なサーバーにキャッシュすることができます。
この章のここまでの一般的な提案はすべてGraphicsアプリケーションにも適用されます。さらに、次の項目について考慮します。
グラフィックを使用するアプリケーションの起動時間は、OGDグラフィック・ファイルを事前ロードすればより高速になります。ランタイム時に必要なファイルが分からない場合は、ダミーのOGDを作成し事前ロードすることができます。
ほとんどのGraphics PL/SQLビルトインへの引数の一つである更新フラグのダメージの理解および制御ダメージ・フラグをデフォルトにできる場合、Graphicsの図表リストが変更されるたびに再描画が発生することを示すTRUEに設定します。このような再描画は必ずしも必要ではありません。
(ボタン・プロシージャ、トリガーなどを含む)PL/SQLプログラム単位が図表を一度に更新すれば、パフォーマンスが改善されます。更新は、必要がなければループに含めないでください。
FormsまたはReportsからGraphicsアプリケーションをコールする場合、できるだけ多くの要素を共有するように設計します。たとえば、すでにFormsがフェッチしたデータをチャートにする場合、(図表がデータベースに再問合せするのではなく)同じデータを渡してレコード・グループに表示します。
すべてのデータが共有され、Graphicsアプリケーションがデータベース・サーバーをコールする必要がなければ、Graphicsアプリケーションがコールされるときに、LOGON
パラメータをNOに設定します(LOGON
がNOに設定されていない場合は、Graphicsがサーバーに再接続するため、起動が遅くなります)。
同様に、フォームまたはレポートおよび図表では、同じカラー・パレットおよび同じフォントを使用します。さらに、できるだけ同じ座標系を使用します。
DO_SQLプロシージャはDDL文の実行に使用することができます。ただし、このプロシージャはDML文の実行には使用しないでください。一般に、DML文はDO_SQLプロシージャを使用するよりも、プログラム内で実行する方がより効率的です。
ビルトイン・サブプログラムを使用してGraphicsオブジェクト上で操作する場合は、オブジェクトを識別する必要があります。PL/SQLで何度もオブジェクトを参照する場合、オブジェクトにハンドル(つまり、ポインタ)を割り当て、名前でオブジェクトを識別するのではなく、ハンドルでオブジェクトを識別するとより効率的です。ハンドルを使用することで内部検索時間を削減することができます。
Graphicsは、オブジェクトの作成のプロセス、属性の取得または設定を簡単にする、一連のビルトイン・サブプログラムを提供します。属性レコード・アプローチのかわりに、これらのビルトインを使用することで、開発時間を短縮し、読みやすく理解しやすいプログラム単位にすることができます。
ただし、これらのビルトインの使用には実行時のパフォーマンスにマイナスの影響を与えます。ビルトイン問合せをコールするたびに、Graphicsは新しい内部属性レコードを定義し移植する必要があります。また複数のルーチンの実行には、1つのみのルーチンの実行よりも時間がかかります。さらに、これらのビルトイン問合せを使用する場合、アプリケーションはデフォルト設定に依存する必要があります。
おおまかなガイドラインとしては、3つ以上の属性を設定する必要がある場合には、属性マスクを使用するか、または事前定義済みのデフォルトを使用して独自のショートカットのライブラリを作成する方が効率的です。
従来のクライアント/サーバー構造では、アプリケーションはクライアント上で実行され、データベースとそのソフトウェアはサーバー側に常駐します。この章のここまでの一般的な提案はすべてクライアント/サーバーの設定にも適用されます。さらに、次のクライアント/サーバー固有の提案について考慮します。
Forms DeveloperおよびReports Developerでは、インストール時にソフトウェアの格納場所を選択することができます。各構成には長所と短所があります。状況に応じて最適な構成を選択してください。
アプリケーションを作成した後、クライアントまたはサーバーのどちらに保存するかを選択できます。サーバー側にアプリケーションを保存すると、アプリケーションへのアクセスの共有が可能になり、クライアント側のディスク領域の節約にもなります。一方、アプリケーションをローカルのクライアントに保存すると、高速にアクセスできます。
ディスク領域と共有に関する考慮事項に加え、サーバーへ保存すると、さらに優れたセキュリティが提供されます。
これらの考慮事項の中から状況に最も適した保存先を選択します。
3層構造では、第1層は実行時のユーザーのデスクトップです。これはFormsクライアント部分として知られるFormsランタイム製品の一部をロードするJavaアプレットを実行します。第2層はアプリケーション・サーバーです。Formsサーバー部分として知られるFormsランタイム製品の残りの部分を実行します。第3層はデータベース・サーバーです。FormsクライアントとFormsサーバー間、およびFormsサーバーとデータベース・サーバー間で通信が行われます
この章のここまでの一般的な提案はすべて3層構造にも適用されます。たとえば、アプリケーション・サーバー・コンポーネントとデータベース・サーバーとの対話は、2層クライアント/サーバー環境のアプリケーション・サーバーとデータベースとの対話と本質的には同一です。このため、PL/SQLの使用の改善やデータベースの効率的な使用などの領域はここでも関連します。
3層環境では、アプリケーション・サーバーとデータベース(第2層と第3層)間のみでなく、デスクトップ機のクライアントとアプリケーション・サーバー(第1層と第2層)間でも通信が行われます。このため、ネットワーク利用を減少させることがここで説明する重要な領域になります。
以下の提案は3層環境に固有の提案です。
第1層のデスクトップ機のクライアントとアプリケーション・サーバー機のサーバーとの対話は、エンド・ユーザー数が増加するにつれて、より重要なものになっていきます。次の提案は、アプリケーションのスケーラビリティを最大化するのに役立ちます(これらの提案は、どのForms DeveloperアプリケーションおよびReports Developerアプリケーションにも適用されます)。
第1層と第2層の間のネットワーク接続は通常3層環境では頻繁に使用されるため、ネットワーク効率がパフォーマンスの重要な領域となります。ここの帯域幅を増やすことで、かなりの改善をもたらすことができます。
実行中にユーザー・インタフェースに変更するには、第1層と第2層間で対話が必要になります。このような変更は(エンド・ユーザーが感じる)パフォーマンスを低下させます。
次のタイプのランタイム・アクティビティを避けることで実行を高速にすることができます。
一般原則として、画面の頻繁なリフレッシュに関係するアクティビティは制限します。たとえば、短い間隔の可視タイマーまたはクロックの使用は避けてください(1分より長い間隔のタイマーであれば、通常問題ありません)。ユーザー・インタフェースは経過クロック時間ではなく、ユーザーからの対話によってイベントを開始するように設計します。
アプリケーションでスタック・キャンバスを使用する場合、可視プロパティを「いいえ」に設定し、エントリでレイズ・プロパティを「いいえ」に設定します。これは、実行時のインタフェースへの変更を最小化します。
上位レベルで妥当性チェックを行うようにします。アプリケーションの設計およびスケーラビリティの決定がトレードオフに関わる場合があります。たとえば、フィールド・レベルの妥当性チェックは、ブロック・レベルの妥当性チェックよりもかなり多くのネットワーク通信量を発生しますが、ユーザーにとってはより対話的です。
プログラム的にメニュー項目を使用可や使用不可にすると、Webformsのパフォーマンスが低下します。
アプリケーションでグラフィックを使用する場合、表示するファイルのサイズを制限するとパフォーマンスの低下を防ぎます。表示サイズを小さくするには、たとえば次のようにします。
アプリケーションでグラフィック(JPGファイル)を使用する場合、環境変数FORMSnn_MAPPING
とFORMSnn_PATH
を使用してURLの場所を識別します。
マルチメディアはユーザー・インタフェースにとって重要な場合のみ使用します。マルチメディアを使用する場合は、メディア情報を含むURLをコールするボタン・トリガーを定義(または再定義)します。
ネットワーク上でアニメーションを実行すると非常にコストがかかります。このような要素が必要な場合は、クライアント側にあるグラフィック・ファイルのアニメーションの使用を考えてください。
カスタム・ハイパーリンクを利用して、ハイパーリンク・ドリルダウンを作成します。このテクニックを使用する場合、コードは実際に必要になるまでユーザーのマシンにはロードされません。
できるだけ多くのコードをライブラリに入れて、オブジェクトおよびアプリケーション間で共有するコードを最大限に増やし、ロード中のファイル・サイズを最小に抑えます。
リリース2.0以降、ライブラリは複数のフォーム間で共有されています。つまり、各フォームごとにプログラム単位が再ロードされ、アンパックする必要がないということです。メモリーにはプログラム単位のコピーが1つしかないため、メモリーもそれほど使用しません。
デスクトップ機でアプリケーションの実行を開始する時には、いくつかのJavaクラス・ファイルが利用可能となっている必要があります。一般的なアプリケーションでは、これらのファイルは大量にあり、サーバーからこれらをダウンロードすると起動オーバーヘッドが増加します。
リリース6.0以降では、これらのJavaクラス・ファイルのいくつかをJARファイルとしてパッケージしています。JARファイルは、アプリケーション起動が高速になるように、アプリケーション・サーバーではなくデスクトップ機に保存することができます。
アプリケーションに必要な残りのクラス・ファイルも、デスクトップ機のJARファイルに加えることができます。これはOracle Java Developer Kitを使用して行うことができます。
高速なユーザー・インタフェースが望ましい状況では、アプリケーションを事前ロードすると便利です。つまり、実際に集中的な利用が必要となる前に開始します。このようにして、初期ロード段階が完了しているため後続でのコールが高速になります。
デスクトップからアプリケーションが起動されると、ユーザーはコンパイルしない状態でダウンロードして、デスクトップで実行を開始する時にコンパイルするように選択することができます。このオプションは呼出し時間全体を高速にします。
第2層と第3層の対話(アプリケーション・サーバーとデータベース・サーバー間の対話)のための提案は、この章で先に記述したクライアント/サーバー環境のための提案と同じです。たとえば、DML配列サイズ・プロパティやストアド・プロシージャに基づくデータ・ブロックなどを使用することができます。データベース対話のための先の提案はすべてここでも適用されます。
3層システムの基本となるハードウェアすべての能力を増加すると、ほぼ確実にパフォーマンスに好影響を与えます。
最近のテスト結果では、第2層プロセッサの処理能力のアップグレードによって、最も顕著な改善が得られることを提案しています。ただし、各サイトおよび状況はそれぞれ異なり、これらの結果が一般的に適用できるわけではありません。
3層構造では第2層コンポーネントの複数のバージョンを使用することができます。Forms DeveloperまたはReports Developerサーバー・コンポーネントのコピーを実行する、複数の中間サーバー・マシンを利用できます。
処理を統合するにはOracle Application Serverを使用します。クライアント(第1層)マシンからの要求はOracle Application Serverへ送られ、Oracle Application Serverから第2層サーバーのいずれかへ渡されます。
複数の第2層サーバー操作とワーク・ロードの共有によって、第2層のパフォーマンスが改善されます。
|
Copyright © 2000 Oracle Corporation. All Rights Reserved. |
|