DBAの要求は意味がありません。
DBAがほぼ確実に考えているのは、カーソルからデータをフェッチするときに発生するSQLからPL/SQLエンジンへのコンテキストシフトの数を最小限に抑えたいということです。しかし、提案されている解決策は、この特定の問題を十分に対象としておらず、ほとんどのシステムで他のはるかに深刻なパフォーマンスの問題を引き起こします。
Oracleでは、PL / SQLVMがSQLVMに追加のデータを要求すると、SQLからPL / SQLへのコンテキストシフトが発生します。SQLVMは、ステートメントをさらに実行してデータを取得し、パッケージ化してPLに返します。 /SQLVM。 PL / SQLエンジンが一度に1行ずつ要求し、多数の行をフェッチしている場合、これらのコンテキストシフトがランタイム全体のかなりの部分を占める可能性があります。この問題に対処するために、オラクルは少なくとも8i日間で一括操作の概念を導入しました。これにより、PL /SQLVMはSQLVMから一度に複数の行を要求できました。 PL / SQL VMが一度に100行を要求する場合、コンテキストシフトの99%が排除され、コードがはるかに高速に実行される可能性があります。
一括操作が導入されると、BULK COLLECT
を明示的に使用することで効率を高めるために、リファクタリングできるコードがたくさんありました。 行ごとにフェッチしてからFORALL
を使用するのではなく、操作 それらのコレクションのデータを処理するためのループ。ただし、10.2日までに、オラクルは一括操作を暗黙のFOR
に統合していました。 ループするので、暗黙のFOR
ループは、行ごとにフェッチするのではなく、100のバッチで自動的に一括収集するようになりました。
ただし、あなたの場合、データをクライアントアプリケーションに返すため、一括操作の使用はそれほど重要ではありません。適切なクライアント側APIには、各ネットワークラウンドトリップでカーソルからフェッチする必要のある行数をクライアントが指定できる機能があり、それらのフェッチ要求はPLを介さずにSQLVMに直接送信されます。 / SQL VMであるため、SQLからPL/SQLへのコンテキストシフトについて心配する必要はありません。アプリケーションは、各ラウンドトリップで適切な数の行をフェッチすることを心配する必要があります。アプリケーションがネットワーク上でおしゃべりになりすぎたりボトルネックになったりすることはありませんが、結果が出るまで長く待たなければならないほど多くはありません。返されるか、メモリに保存するデータが多すぎます。
REFCURSORではなくPL/SQLコレクションをクライアント・アプリケーションに返しても、発生するコンテキスト・シフトの数は減りません。しかし、メモリ使用量だけでなく、他にも多くの欠点があります。 PL / SQLコレクションは、データベースサーバーのプロセスグローバル領域(PGA)(専用サーバー接続を想定)に完全に格納する必要があります。これは、サーバーのRAMから割り当てる必要のあるメモリのチャンクです。つまり、サーバーは、すべてのクライアントが要求するすべての最後の行をフェッチするためのメモリを割り当てる必要があります。その結果、アプリケーションのスケーラビリティが劇的に制限され、データベース構成によっては、アプリケーションのパフォーマンスを向上させるのに非常に役立つOracleデータベースの他の部分からRAMが奪われる可能性があります。また、PGAスペースが不足すると、セッションでメモリ関連のエラーが発生し始めます。純粋にPL/SQLベースのアプリケーションであっても、使用しているPGAの量を最小限に抑えるために、すべてのデータをコレクションにフェッチすることは決してありません。常に小さなバッチでフェッチする必要があります。
さらに、すべてのデータをメモリにフェッチすると、アプリケーションの動作が非常に遅くなります。ほとんどすべてのフレームワークで、必要に応じてデータをフェッチできます。たとえば、各25行のページで表示しているレポートがある場合、アプリケーションは最初の25行をフェッチするだけでペイントできます。最初の画面。また、ユーザーがたまたま結果の次のページを要求しない限り、次の25行をフェッチする必要はありません。ただし、DBAが提案するようにデータを配列にフェッチする場合は、ユーザーが最初の一握り以上を表示したくない場合でも、アプリケーションが最初の行の表示を開始する前に、すべての行をフェッチする必要があります。行。これは、すべての行をフェッチするためのデータベースサーバーでのI / Oの増加、サーバーでのPGAの増加、結果をバッファリングするためのアプリケーションサーバーでのRAMの増加、およびネットワークの待機時間の延長を意味します。