2

特定の条件に基づいて、数百万のレコードを含むテーブルを更新する必要があるという問題があります。それを行うために長いシェル スクリプトと SQL ステートメントを作成しました。パフォーマンスを確認するために、Explain Plan を使用して調査する予定ですhttp://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm#19259

ここには、「実行計画は次の理由で異なる場合がある」と書かれています: コストの違い -> データ量と統計情報 バインド変数の種類 初期化パラメータ - グローバルまたはセッション レベルで設定

ここでは、初期化パラメーターがどのようにグローバルまたはセッションレベルで設定され、実行計画に影響するかを理解していません。誰もこれを説明できますか?また、Explain Plan または Autotrace 以外の SQL ステートメントのパフォーマンスをチェックする方法はありますか。

4

3 に答える 3

3

ステートメントの実行計画に影響を与える可能性のある (初期化) パラメーターがいくつかあります。すぐに思い浮かぶのはOPTIMIZER_MODEです

その他のそれほど明白ではないセッションは、インデックスの使いやすさに影響を与える可能性のある NLS 設定などです。

(セッションをトレースして tkprof を使用する以外に) 実際の実行計画を取得する別の方法は、/*+ gather_plan_statistics */ヒントを 'dbms_xplan.display_cursor()' と共に使用することです。

これは、最初に上記のヒントを使用してステートメントを実際に実行することによって行われます (したがって、これには「通常の」説明よりも時間がかかります)。

select /*+ gather_plan_statistics */ * 
from some_table
  join ...
where ...

そのステートメントが終了したら、dbms_xplan を使用して使用済みのプランを取得できます。

SELECT * 
FROM table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST');
于 2012-08-01T08:28:16.537 に答える
1

個人的には、行ソース操作のみを信頼します。これにより、実行されたとおりの正確な計画が得られるからです。計画の作成方法に影響を与えるいくつかのパラメーターが存在します。ほとんどのパラメータはインスタンスレベルで設定されますが、セッションレベルでオーバーライドできます。これは、すべてのセッションが独自の有効なパラメータのセットを持つことができることを意味します。

あなたが抱えている問題は、スクリプトを実行しようとしているセッションの正確な設定を知る必要があるということです。セッションレベルの設定を変更する方法はいくつかあります。設定は、ログオントリガー、ストアドプロシージャ、またはスクリプトで変更できます。

スクリプトがログオントリガーの影響を受けず、ステートメントを発行するコードを呼び出さないalter session場合は、インスタンスの設定を使用します。

于 2012-08-01T07:49:53.740 に答える
1

GLOBAL OR SESSION パラメータ Oracle は、一連の初期化パラメータを使用してセットアップされます。それらを上書きするために何も指定されていない場合、それらはデフォルトで使用されます。これらは、ALTER SESSION (1 人のユーザーにのみ影響する) または ALTER SYSTEM (Oracle が再起動されるまですべてのユーザーに影響する) コマンドを使用してセッションまたはシステム レベルで変更するか、コード内のオプティマイザー ヒントを使用することによってオーバーライドできます。これらは、表示される計画に影響を与える可能性があります。

説明計画に関連して、異なる Oracle データベースには異なる初期化パラメーターがあるか、いくつかのセッション/システムパラメーターが設定されている可能性があります。これは、同じコードの動作が異なることを意味する可能性があります (ある Oracle データベースで別の Oracle データベースと比較して異なる実行計画を取得することにより)。

また、実行計画は選択したデータの影響を受けるため、TEST で正常に実行されたクエリまたはパッケージが、データ量がはるかに多い PRODUCTION では決して終了しない可能性があります。これは、コードが正確な量のデータでテストされていない場合によくある問題です (または、テストが実稼働のようなデータの全量を保持できない場合は、少なくとも実稼働データベースからインポートされたテーブル統計を使用して)。

追跡 これまでの提案は、どのステートメントに問題があるかはわかっているものの、複数の SQL ステートメントを含むシェル スクリプトがあると言及した場合に、個々のステートメントを追跡する方法を示しています。

SQL への 1 回の呼び出しと、このような複数の SQL ステートメントを含むヒア ドキュメントを使用している場合...

 #!/bin/ksh
 sqlplus -S user/pass <<EOF
 set heading off
 BEGIN
      -- DO YOUR FIRST SQL HERE
      -- DO YOUR SECOND SQL HERE
 END;
 /

 EOF

... このように 1 つの Oracle トレース ファイルを作成できます

 #!/bin/ksh
 sqlplus -S user/pass <<EOF
 set heading off
 BEGIN
      ALTER SESSION SET EVENTS '10046 trace name context forever, level 8'
      -- DO YOUR FIRST SQL HERE
      -- DO YOUR SECOND SQL HERE
 END;
 /

 EOF
  • レベル 8 は、WAITS を使用したトレース用であることに注意してください。レベル 4 (変数のバインド) とレベル 12 (バインドと待機) を実行できますが、私は常にレベル 8 だけで問題を発見しました。

次に、シェル スクリプトを実行して 1 回実行し、SQL PLUS でトレース ファイルが作成された場所を確認します。

  SQL> show parameter user_dump_dest
  /app/oracle/admin/rms/udump

そのディレクトリに移動すると、他のトレースが有効になっていない場合は、スクリプト内の SQL の実行全体のトレースを含む .trc ファイルが作成されます。

次のような unix tkprof コマンドを使用して、これを読み取り可能な形式に変換する必要があります。

  unix> tkprof your.trc ~/your.prf sys=no sort=fchela,exeela

ここでホーム ディレクトリに移動すると、SQL ステートメントが最も実行時間またはフェッチ時間がかかるものから順にリストされた .prf ファイルが作成されます。この tkprof へのパラメーターのセットにより、最も時間がかかり、チューニングの効果が最大になるステートメントの修正に集中することができます。

シェル スクリプトが複数の sqlplus コマンドを実行する場合、それぞれが個別のセッションを作成するため、それぞれに ALTER SESSION ステートメントを追加すると、個別のトレース ファイルが作成されることに注意してください。

また、詳細に迷いやすいことを忘れないでください。チューニングとは、全体像を見て、同じことを別の方法で行うことである場合があります。単一の SQL に取り組むことから始めるのではなく、数秒かかる可能性がありますが、全体的なスキームで行います。全体の実行時間を短縮するのに役立ちません。

可能であれば、1 つの大きなテーブルがあるかのように、更新ステートメントの数を最小限に抑えるようにしてください。多くのことを行うよりも、テーブルの 1 回のパスで更新を実行できる (そして更新をサポートするインデックスがある) 方が効率的です。小さな更新。

さらに支援が必要な場合は、スクリプトの関連部分、実行にかかる全体の時間、説明計画を投稿できます。

于 2012-08-01T12:52:47.190 に答える