クエリの説明プランをどのように解釈しますか?


88

SQLステートメントがどのように実行されているかを理解しようとするときに、説明計画を確認することが推奨される場合があります。説明プランを解釈する(理解する)際に実行する必要があるプロセスは何ですか?「ああ、これは見事に機能していますか?」対「ああ、そうじゃない」

回答:


80

完全なテーブルスキャンが悪く、インデックスへのアクセスが良いというコメントを見るたびに身震いします。全テーブルスキャン、インデックスレンジスキャン、高速全インデックススキャン、ネストされたループ、マージ結合、ハッシュ結合などは、アナリストが理解し、データベース構造の知識とクエリの目的を組み合わせる必要がある単純なアクセスメカニズムです。意味のある結論に到達するため。

フルスキャンは、データセグメント(テーブルまたはテーブル(サブ)パーティション)のブロックの大部分を読み取る最も効率的な方法であり、多くの場合、パフォーマンスの問題を示す可能性がありますが、これはコンテキストのみです。クエリの目標を達成するための効率的なメカニズムであるかどうかの判断。データウェアハウスおよびBIの人として言えば、パフォーマンスに関する私の最大の警告フラグは、インデックスベースのアクセス方法とネストされたループです。

したがって、Explain Planを読み取る方法のメカニズムについては、Oracleのドキュメントが適切なガイドです。http//download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

パフォーマンスチューニングガイドもよく読んでください。

また、「カーディナリティーフィードバック」のグーグルを持っています。この手法では、説明計画を使用して、クエリのさまざまな段階でのカーディナリティの推定値を、実行中に実際に発生したカーディナリティと比較できます。ヴォルフガング・ブライトリングがこの方法の作者であると私は信じています。

つまり、アクセスメカニズムを理解する必要があります。データベースを理解します。クエリの意図を理解します。経験則を避けてください。


5
最初の9ワードを読んだ後、それがあなたであることがわかった 「チューンネーム」のようなものです...デイブAの投稿をn語以下で識別できます...

「大きな」を使用すると、少し混乱します...場合によっては、データがインデックス列の周りに十分にクラスター化されていないため、FTSが行の10%でもインデックススキャンを実行できないことがあります...

1
10%-絶対に。ブロックごとに200行あり、行の0.5%を探している場合、理論上はすべての値を取得するためにブロックの100%にアクセスする必要があるため、10%よりも極端になります。
David Aldridge、


5

以下の2つの例は、INDEXを使用したFULLスキャンとFASTスキャンを示しています。

コストとカーディナリティに集中することをお勧めします。例を見ると、インデックスを使用すると、クエリを実行するコストが削減されます。

これは少し複雑です(100%のハンドルはありません)が、基本的にはコストはCPUとIOのコストの関数であり、カーディナリティはOracleが解析することを期待する行数です。これらの両方を減らすことは良いことです。

クエリのコストは、クエリとOracleオプティマイザーモデル(例:COST、CHOOSEなど)、および統計を実行する頻度によって影響を受ける可能性があることを忘れないでください。

例1:

SCAN http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

インデックスを使用した例2:

INDEX http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

そしてすでに示唆したように、TABLE SCANに注意してください。通常、これらは回避できます。


ええと、ルールモードにはコストがありません...だから、あなたの発言はある種の絶対的な方法で正しいと思いますが、それは根本的に不正確だと思います。CHOOSEと言うと、RBOまたはCBOを取得できます。CBOは、コストを計算する唯一のものです。

4

シーケンシャルスキャンのようなものを探すことはいくらか便利ですが、現実は数にあります...数が単なる推定値である場合を除きます!通常、クエリプランを見るよりもはるかに役立つのは、実際の実行を調べることです。Postgresでは、これがEXPLAINとEXPLAIN ANALYZEの違いです。EXPLAIN ANALYZEは実際にクエリを実行し、すべてのノードの実際のタイミング情報を取得します。これにより、計画担当者何が起こると考えるのではなく、実際に起こっているのかを確認できます。多くの場合、シーケンシャルスキャンはまったく問題ではなく、クエリの他の問題です。

もう1つのキーは、実際の高額なステップを特定することです。多くのグラフィカルツールは、異なるサイズの矢印を使用して、計画のさまざまな部分のコストを示します。その場合は、細い矢印が入り、太い矢印が出るステップを探してください。GUIを使用していない場合は、数値に注目し、突然大きくなる場所を探す必要があります。少し練習すれば、問題のある領域を簡単に見つけることができます。


3

本当にこれらのような問題の場合、行うべき最善のことはASKTOMですです。特に、その質問に対する彼の回答には、そのような種類のルールの多くが説明されているオンラインのOracleドキュメントへのリンクが含まれています。

心に留めておくべきことの1つは、説明計画は本当に最良の推測であることです。

sqlplusの使用方法を学び、AUTOTRACEコマンドを試すことをお勧めします。いくつかの難しい数値があれば、一般的にはより良い決定を下すことができます。

ただし、ASKTOMを使用する必要があります。彼はそれについてすべて知っています:)


2

Explainの出力は、各ステップの所要時間を示しています。最初に、長い時間を費やしているステップを見つけ、それらの意味を理解する必要があります。シーケンシャルスキャンのようなものは、より優れたインデックスが必要であることを示しています。これは主に、特定のデータベースと経験に関する研究の問題です。


2

1つは「ああ、そうじゃない」は、多くの場合、テーブルスキャンの形式です。テーブルスキャンは特別なインデックスを利用せず、メモリキャッシュ内のすべての有用なオブジェクトの削除に貢献できます。たとえば、postgreSQLでは、次のようになります。

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

たとえば、インデックスを使用して行をクエリするよりも、テーブルスキャンが理想的である場合があります。ただし、これは、ユーザーが探していると思われる赤信号パターンの1つです。


2
(フル)テーブルスキャンは、必ずしもメモリキャッシュをパージするわけではありません。
a_horse_with_no_name 2012

2

基本的に、各操作を見て、操作がどのように機能するかについての知識を与えられた操作が「理にかなっている」かどうかを確認します。

たとえば、2つのテーブルAとBをそれぞれの列CとD(AC = BD)で結合していて、プランでテーブルにクラスター化インデックススキャン(SQL Server用語-oracle用語が不明)が表示されている場合A、次に、テーブルBで一連のクラスター化インデックスシークへのネストされたループ結合を行うと、問題が発生したと思われるかもしれません。そのシナリオでは、エンジンが(結合された列のインデックスに対して)インデックススキャンのペアを実行し、その後にマージ結合を実行することを期待できます。さらなる調査により、オプティマイザがその結合パターン、または実際には存在しないインデックスを選択するようになる、不適切な統計が明らかになる可能性があります。


1

計画の各サブセクションに費やされた時間の割合を見て、エンジンが何をしているかを考えます。たとえば、テーブルをスキャンしている場合は、スキャンしているフィールドにインデックスを付けることを検討してください。


1

主にインデックスまたはテーブルスキャンを探します。これは通常、whereステートメントまたはjoinステートメントにある重要な列にインデックスがないことを示しています。

http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspxから:

実行計画に次のいずれかが表示された場合は、それらの警告サインを考慮し、潜在的なパフォーマンスの問題がないか調査する必要があります。それらのそれぞれは、パフォーマンスの観点から理想的ではありません。

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

これらを常に回避できるとは限りませんが、回避できるほど、クエリのパフォーマンスが向上します。


1
テーブルスキャンはすべてが悪いわけではありません。テーブルから返される/処理されるレコードの数によっては、フルテーブルスキャンはインデックススキャンよりも高速になる場合があります(とにかくレコードを戻す場合は、インデックススキャンを実行します)テーブルからの完全な読み取り-1)ではなく2ステップ。
ScottCher 2008年

-7

経験則

(おそらく、詳細についても読みたいでしょう:

悪い

いくつかの大きなテーブルのテーブルスキャン

良い

一意のインデックスの使用
インデックスにはすべての必須フィールドが含まれています

最も一般的な勝利

私が見たパフォーマンスの問題の約90%で、最も簡単な方法は、多数(4以上)のテーブルを含むクエリを2つの小さなクエリと一時テーブルに分割することです。


2
テーブルスキャンはよく悪いことと見なされがちですが、それは最初は経験の浅い人が注目することです。これは、そのテーブルから返されるレコードの数に大きく依存します。インデックスルックアップよりもフルテーブルスキャンを実行するほうが高速な場合、しきい値があります。
ScottCher 2008年

8
とんでもないアドバイスに反対票を投じた。パフォーマンスの問題の90%は、一時テーブルとクエリの分割では解決されません。あなたはどの世界に住んでいますか?
TheSoftwareJedi 2008年

@ジェダイ、私はお世話になっている世界がほとんどで、データベースはかなり敏感に構造化されている世界に住んでいます。しかし、私はあなたの答えを読みたいと思います。
AJ。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.