73

クエリを最適化しようとしていますが、Explain Planから返される情報の一部がよくわかりません。OPTIONS 列と COST 列の重要性を教えてもらえますか? OPTIONS 列には、FULL という単語しか表示されません。COST 列では、コストが低いほどクエリが高速になると推測できます。しかし、コスト値は正確には何を表し、許容可能なしきい値は何ですか?

4

5 に答える 5

122

EXPLAIN PLAN の出力は、Oracle のクエリ オプティマイザからのデバッグ出力です。COST は、コストベースのオプティマイザ (CBO) の最終出力であり、その目的は、クエリを実行するために使用する必要がある多くの異なる計画のどれを選択することです。CBO は各プランの相対的なコストを計算し、コストが最も低いプランを選択します。

(注: 場合によっては、CBO が考えられるすべての計画を評価するのに十分な時間がないことがあります。このような場合、これまでに見つかったコストが最も低い計画を選択するだけです)

一般に、遅いクエリの最大の原因の 1 つは、クエリを処理するために読み取られる行数 (より正確にはブロック)です。読まれます。

たとえば、次のクエリがあるとします。

SELECT emp_id FROM employees WHERE months_of_service = 6;

(months_of_service列には NOT NULL 制約があり、通常のインデックスがあります。)

オプティマイザがここで選択する基本的な計画は 2 つあります。

  • 計画 1: 「employees」テーブルからすべての行を読み取り、それぞれについて、述語が true ( months_of_service=6) かどうかを確認します。
  • プラン 2: インデックス where months_of_service=6(これにより一連の ROWID が生成されます) を読み取り、返された ROWID に基づいてテーブルにアクセスします。

"employees" テーブルに 1,000,000 (100 万) 行あるとします。months_of_service の値が 1 から 12 の範囲で、何らかの理由でかなり均等に分散されているとさらに想像してみましょう。

FULL SCAN を含むPlan 1のコストは、 employees テーブルのすべての行を読み取るコストであり、およそ 1,000,000 に等しくなります。しかし、Oracle はマルチブロック読み取りを使用してブロックを読み取ることができることが多いため、実際のコストは (データベースの設定方法に応じて) 低くなります。たとえば、マルチブロック読み取りカウントが 10 であると仮定してみましょう。フルスキャンは 1,000,000 / 10 になります。総コスト = 100,000。

INDEX RANGE SCAN と ROWID によるテーブル ルックアップを含むPlan 2のコストは、インデックスをスキャンするコストと、ROWID によってテーブルにアクセスするコストです。インデックス レンジ スキャンのコストについては説明しませんが、インデックス レンジ スキャンのコストが行ごとに 1 であると想像してみましょう。12 件中 1 件で一致が見つかると予想されるため、インデックス スキャンのコストは 1,000,000 / 12 = 83,333 です。+ テーブルへのアクセスのコスト (アクセスごとに 1 ブロック読み取りを想定。ここではマルチブロック読み取りは使用できません) = 83,333; 全体のコスト = 166,666。

ご覧のとおり、プラン 1 (フル スキャン) のコストは、プラン 2 (インデックス スキャン + ROWID によるアクセス) のコストよりも低くなります。これは、CBO がフル スキャンを選択することを意味します。

ここでオプティマイザーが行った仮定が正しい場合、実際にはプラン 1 が好ましく、プラン 2 よりもはるかに効率的です。これは、FULL スキャンが「常に悪い」という神話を反証します。

オプティマイザーの目標が ALL_ROWS ではなく FIRST_ROWS(n) である場合、結果はまったく異なります。この場合、オプティマイザーはプラン 2 を優先します。これは、クエリ全体の効率が低下する代わりに、最初の数行がより速く返されることが多いためです。 .

于 2009-05-15T07:20:47.037 に答える
7

CBOは決定木を構築し、クエリごとに利用可能な各実行パスのコストを見積もります。コストは、インスタンスに設定されたCPU_costまたはI/O_costパラメーターによって設定されます。また、CBOは、クエリが使用するテーブルとインデックスの既存の統計を使用して可能な限りコストを見積もります。コストだけに基づいてクエリを調整するべきではありません。コストにより、オプティマイザが何をしているのかを理解できます。コストをかけずに、オプティマイザーが実行したプランを選択した理由を理解できます。コストが低いからといって、クエリが高速になるわけではありません。これが正しい場合と間違っている場合があります。コストはテーブルの統計に基づいており、それらが間違っている場合、コストは間違っています。

クエリを調整するときは、各ステップのカーディナリティと行数を確認する必要があります。それらは意味がありますか?オプティマイザが正しいと想定しているカーディナリティはありますか?返される行は妥当ですか。存在する情報が間違っている場合、オプティマイザが正しい決定を行うために必要な適切な情報を持っていない可能性が非常に高くなります。これは、cpu-statsだけでなく、テーブルとインデックスの統計が古くなっているか欠落していることが原因である可能性があります。オプティマイザーを最大限に活用するためにクエリを調整するときは、統計を更新するのが最善です。スキーマを知ることも、チューニング時に非常に役立ちます。オプティマイザーが本当に悪い決定をいつ選択したかを知り、それを小さなヒントで正しいパスに向けることで、時間の負荷を節約できます。

于 2009-05-14T17:41:14.137 に答える
6

Oracle で EXPLAIN PLAN を使用するためのリファレンスは次のとおりです: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm ) 。 /download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm#i18300

「FULL」についての言及は、クエリがデータを見つけるためにフルテーブルスキャンを実行していることを示しています。これは、特定の状況では問題ありませんが、それ以外の場合は、インデックス作成/クエリの作成が不十分であることを示しています。

一般に、実行計画では、クエリがキーを利用していることを確認する必要があります。これにより、Oracle は可能な限り少ない行数にアクセスして、探しているデータを見つけることができます。最終的には、テーブルのアーキテクチャでしか達成できないことがあります。コストが高すぎる場合は、スキーマのレイアウトをよりパフォーマンスに基づいたものに調整することを検討する必要があります。

于 2009-05-13T21:25:43.103 に答える
3

最近の Oracle バージョンでは、COST は、オプティマイザーがクエリにかかると予想する時間を表し、単一のブロック読み取りに必要な時間の単位で表されます。

したがって、1 つのブロックの読み取りに 2 ミリ秒かかり、コストが「250」と表されている場合、クエリが完了するまでに 500 ミリ秒かかると予想できます。

オプティマイザーは、単一ブロックおよびマルチブロック読み取りの推定数と、プランの CPU 消費量に基づいてコストを計算します。後者は、特定の操作を他の操作の前に実行して、CPU コストの高い操作を回避することで、コストを最小限に抑えるのに非常に役立ちます。

これにより、オプティマイザーが操作にかかる時間をどのように知るかという問題が生じます。最近の Oracle バージョンでは、「システム統計」の収集が可能です。これは、テーブルまたはインデックスの統計と混同しないでください。システム統計は、ハードウェアのパフォーマンスの測定値であり、主に次のことが重要です。

  1. 1 つのブロック読み取りにかかる時間
  2. マルチブロック読み取りにかかる時間
  3. マルチブロック読み取りの大きさ (多くの場合、テーブルのエクステントが最大値よりも小さいなどの理由により、可能な最大値とは異なります)。
  4. CPU パフォーマンス

これらの数値は、システムの動作環境によって大きく異なる可能性があり、必要に応じて、「昼間の OLTP」操作と「夜間のバッチ レポート」操作、および「月末レポート」操作に対して異なる統計セットを保存できます。

これらの一連の統計を考慮して、特定のクエリ実行プランをさまざまな動作環境でのコストを評価できます。これにより、ある場合には全テーブル スキャンの使用が促進され、別の場合にはインデックス スキャンの使用が促進される可能性があります。

コストは完全ではありませんが、オプティマイザーはリリースごとに自己監視を改善し、将来のより良い決定を下すために、推定コストと比較して実際のコストをフィードバックできます。これにより、予測がかなり難しくなります。

並列クエリ操作は複数のスレッドで合計時間を消費するため、コストは必ずしも実時間ではないことに注意してください。

古いバージョンの Oracle では、CPU 操作のコストは無視され、単一およびマルチブロック読み取りの相対的なコストは、init パラメータに従って効果的に固定されていました。

于 2013-09-02T09:42:49.237 に答える
1

FULL はおそらく全テーブル スキャンを参照しており、これはインデックスが使用されていないことを意味します。これは通常、クエリがテーブル内のすべての行を使用することになっていない限り、何かが間違っていることを示しています。

コストは、さまざまな負荷、プロセッサ、メモリ、ディスク、IO の合計を示す数値であり、通常、高い数値は悪いものです。計画のルートに移動するときに数値が合計され、各分岐を調べてボトルネックを特定する必要があります。

v$sql と v$session をクエリして、SQL ステートメントに関する統計を取得することもできます。これにより、あらゆる種類のリソース、タイミング、および実行に関する詳細なメトリックが得られます。

于 2009-05-13T21:26:35.943 に答える