SQLステートメントがどのように実行されているかを理解しようとするときに、説明計画を確認することが推奨される場合があります。説明プランを解釈する(理解する)際に実行する必要があるプロセスは何ですか?「ああ、これは見事に機能していますか?」対「ああ、そうじゃない」
回答:
完全なテーブルスキャンが悪く、インデックスへのアクセスが良いというコメントを見るたびに身震いします。全テーブルスキャン、インデックスレンジスキャン、高速全インデックススキャン、ネストされたループ、マージ結合、ハッシュ結合などは、アナリストが理解し、データベース構造の知識とクエリの目的を組み合わせる必要がある単純なアクセスメカニズムです。意味のある結論に到達するため。
フルスキャンは、データセグメント(テーブルまたはテーブル(サブ)パーティション)のブロックの大部分を読み取る最も効率的な方法であり、多くの場合、パフォーマンスの問題を示す可能性がありますが、これはコンテキストのみです。クエリの目標を達成するための効率的なメカニズムであるかどうかの判断。データウェアハウスおよびBIの人として言えば、パフォーマンスに関する私の最大の警告フラグは、インデックスベースのアクセス方法とネストされたループです。
したがって、Explain Planを読み取る方法のメカニズムについては、Oracleのドキュメントが適切なガイドです。http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009
パフォーマンスチューニングガイドもよく読んでください。
また、「カーディナリティーフィードバック」のグーグルを持っています。この手法では、説明計画を使用して、クエリのさまざまな段階でのカーディナリティの推定値を、実行中に実際に発生したカーディナリティと比較できます。ヴォルフガング・ブライトリングがこの方法の作者であると私は信じています。
つまり、アクセスメカニズムを理解する必要があります。データベースを理解します。クエリの意図を理解します。経験則を避けてください。
この主題は大きすぎて、このような質問に答えることができません。Oracleのパフォーマンスチューニングガイドを読むには、少し時間がかかるはずです。
以下の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に注意してください。通常、これらは回避できます。
シーケンシャルスキャンのようなものを探すことはいくらか便利ですが、現実は数にあります...数が単なる推定値である場合を除きます!通常、クエリプランを見るよりもはるかに役立つのは、実際の実行を調べることです。Postgresでは、これがEXPLAINとEXPLAIN ANALYZEの違いです。EXPLAIN ANALYZEは実際にクエリを実行し、すべてのノードの実際のタイミング情報を取得します。これにより、計画担当者は何が起こると考えるのではなく、実際に何が起こっているのかを確認できます。多くの場合、シーケンシャルスキャンはまったく問題ではなく、クエリの他の問題です。
もう1つのキーは、実際の高額なステップを特定することです。多くのグラフィカルツールは、異なるサイズの矢印を使用して、計画のさまざまな部分のコストを示します。その場合は、細い矢印が入り、太い矢印が出るステップを探してください。GUIを使用していない場合は、数値に注目し、突然大きくなる場所を探す必要があります。少し練習すれば、問題のある領域を簡単に見つけることができます。
1つは「ああ、そうじゃない」は、多くの場合、テーブルスキャンの形式です。テーブルスキャンは特別なインデックスを利用せず、メモリキャッシュ内のすべての有用なオブジェクトの削除に貢献できます。たとえば、postgreSQLでは、次のようになります。
Seq Scan on my_table (cost=0.00..15558.92 rows=620092 width=78)
たとえば、インデックスを使用して行をクエリするよりも、テーブルスキャンが理想的である場合があります。ただし、これは、ユーザーが探していると思われる赤信号パターンの1つです。
基本的に、各操作を見て、操作がどのように機能するかについての知識を与えられた操作が「理にかなっている」かどうかを確認します。
たとえば、2つのテーブルAとBをそれぞれの列CとD(AC = BD)で結合していて、プランでテーブルにクラスター化インデックススキャン(SQL Server用語-oracle用語が不明)が表示されている場合A、次に、テーブルBで一連のクラスター化インデックスシークへのネストされたループ結合を行うと、問題が発生したと思われるかもしれません。そのシナリオでは、エンジンが(結合された列のインデックスに対して)インデックススキャンのペアを実行し、その後にマージ結合を実行することを期待できます。さらなる調査により、オプティマイザがその結合パターン、または実際には存在しないインデックスを選択するようになる、不適切な統計が明らかになる可能性があります。
計画の各サブセクションに費やされた時間の割合を見て、エンジンが何をしているかを考えます。たとえば、テーブルをスキャンしている場合は、スキャンしているフィールドにインデックスを付けることを検討してください。
主にインデックスまたはテーブルスキャンを探します。これは通常、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?
これらを常に回避できるとは限りませんが、回避できるほど、クエリのパフォーマンスが向上します。
(おそらく、詳細についても読みたいでしょう:
いくつかの大きなテーブルのテーブルスキャン
一意のインデックスの使用
インデックスにはすべての必須フィールドが含まれています
私が見たパフォーマンスの問題の約90%で、最も簡単な方法は、多数(4以上)のテーブルを含むクエリを2つの小さなクエリと一時テーブルに分割することです。