3

JDeveloper ADF Webアプリケーションで実行中の問合せに奇妙な問題があります。Oracle 10g データベースに select 文を発行するシンプルな検索フォームです。検索が送信されると、ADF フレームワークは (最初に) クエリを実行し、(2 番目に) " " で囲まれた同じクエリを実行します。select count(1) from (...query...)ここでの目標は、行の総数を取得し、"次の 10 件の結果" を表示することです。ナビゲーション コントロール。

ここまでは順調ですね。問題は、2 番目のクエリ (" " が含まれるクエリ) から得られるとんでもないパフォーマンスから発生しますcount(1)。この問題を調査するために、SQL Developer でクエリをコピー/貼り付け/実行したところ、はるかに優れた応答が得られて驚きました。

ADF と SQL Developer でのクエリの実行を比較するとき、両方の実行の代表的な環境を確保するためにあらゆる手段を講じました。 、どちらの場合も、db とアプリケーション サーバーが新たに (再) 起動されました。

両方のセッションで取得したトレースは、状況を示しています。

ADF で実行されたクエリ:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.97       0.97          0          0          0           0
Fetch        1     59.42     152.80      35129    1404149          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3     60.39     153.77      35129    1404149          0           1

SQL Developer での同じクエリ:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      1.02       1.16          0          0          0           0
Fetch        1      1.04       3.28       4638       4567          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      2.07       4.45       4638       4567          0           1

コメントや提案をお寄せいただきありがとうございます。

4

4 に答える 4

3

わかりました、私はついにこの恐ろしい行動の説明を見つけました. 簡単に言うと、答えは JDeveloper の ViewObject の定義 (チューニング パラメータ) にあります。私が見逃していたのは、次の 2 つの重要なパラメーターでした。

  • FetchMode="FETCH_AS_NEEDED"
  • FetchSize="10"

それらがないと、ADF がメイン クエリを実行し、変数をバインドし、結果をフェッチします。次に、行数を推定しようとして、" select count(1) from (my_query)" で囲まれた同じクエリを起動しますが、...(ドラム ロール)... 変数をバインドしません!!! バインド変数の実際の値を考慮せずに行数を推定することの用途が何であるかは、本当に私を打ち負かします!

いずれにせよ、それはすべて ViewObject の定義にあります: 期待される動作を得るために、次の設定を行う必要がありました:

  • バッチ内のすべての行: 10
  • (チェックあり) 必要に応じて
  • (チェックなし) 行セットのページング時に行の最後のページを埋める

実行計画は役に立ちませんでした(ADFとSQL Developerの両方で同じでした)。違いは、バインドで取得されたトレース・ファイルでのみ確認できました。

だから、今私の問題は解決されました - 最終的に私を解決に導いたすべてのヒントに感謝します!

于 2010-09-01T06:39:05.940 に答える
1

count を使用したクエリは、(カウントするために) すべてのデータを読み取る必要があるため、処理が遅くなります。

他のクエリを実行すると、データの最初のページのみがフェッチされるため、最初の 10 個の結果が得られた後に実行 (カーソルからの読み取り) を停止できます。

最初のクエリで 100 ページまでロードしてみてください。最初のページよりもかなり遅くなる可能性があります。

オンラインでカウントを選択するのがコストがかかりすぎる場合、一般的なトリックは、必要以上に 1 つの項目 (この場合は 11) を選択して、さらにデータがあるかどうかを判断することです。ページ数は表示できませんが、少なくとも「次のページ」ボタンは表示できます。

更新:カウント クエリは、ADF を介して実行した場合にのみ遅く、SQL Developer を介して実行した場合は高速だとおっしゃっていますか?

于 2010-08-31T09:51:29.163 に答える
1

何年にもわたって、「SELECT COUNT...」が予期しない速度低下の原因であることがよくあります。

上記の結果を理解すると、JDeveloper ではクエリに 153 秒かかりますが、SQL Developer では約 4.5 秒しかかかりません。このクエリを使用して、「次の 10 件の結果」コントロールを表示するかどうかを決定します。

ランタイムが 4.5 秒なのか 153 秒なのかが問題になるかどうかはわかりません。最良の場合でも、ページの初期化にはかなり時間がかかるようです。ページから送信されたときに 4.5 秒で応答するクエリを取得できると仮定します。これは、マウスをクリックするだけで別のことを行うためにユーザーを座らせて待つには長い時間です。 . その同じ 4.5 秒で、アプリはページを数回読み込むのに十分なデータを取得できる可能性があります。

ページを埋めるのに必要な数よりも多くのレコードを取得して、利用可能なデータが他にもあるかどうかを判断する@Thiloのアイデアは良いものだと思います。おそらく、これはあなたの状況に適応することができますか?

共有してお楽しみください。

于 2010-08-31T11:24:30.190 に答える
1

それが同じクエリである場合、私は考えることができます:

  • ADFとSQL Developerの異なる設定(SQL*Plusで試しましたか?)
  • 遅い場合に不適切な型の変数をバインドする

しかし、実行計画や SQL がなければ、何とも言えません。

于 2010-08-31T11:14:27.433 に答える