web-dev-qa-db-ja.com

Explain Planを使用してクエリを最適化する方法は?

私は仕事でいくつかのSQLクエリを最適化する仕事をされています。私が見つけたすべては、問題の領域を特定するために説明計画を使用することへのポイントです。説明プランが私に言っていることを正確に知ることができない問題。コスト、カーディナリティ、およびバイトを取得します。

これは何を示しており、これをガイドとしてどのように使用する必要がありますか。数字が小さい方がいいですか?高い方がいい?任意の入力をいただければ幸いです。

または、クエリを最適化するためのより良い方法がある場合、私は興味があります。

20
Jacob Schoen

実際に何をしているのかに応じて、それ以上のものを手に入れます。これをチェックしてください 計画を説明してください ページ。ここでは、Oracleを使用していて、スクリプトを実行して計画の出力を表示する方法を知っていることを前提としています。最初にもっと重要なのは、特定のインデックスを使用しているかどうか、およびそのインデックスがどのように使用されているかを左側で確認することです。結合を行っている場合は、「(Full)」、「(By Index Rowid)」などが表示されます。コストは次に検討すべきことであり、コストが低いほど優れており、インデックスを使用していない結合を実行している場合は、非常に大きなコストが発生する可能性があります。 プランの列の説明 に関する詳細も読むことをお勧めします。

8
carson

また、Oracleを使用していることも前提としています。また、最初に、プランの説明のWebページを確認することをお勧めします。最適化にはたくさんありますが、それは学ぶことができます。

いくつかのヒントが続きます:

まず、誰かがあなたに最適化を任せるとき、彼らはほとんどの場合、究極のパフォーマンスではなく、許容できるパフォーマンスを探しています。クエリの実行時間を3分から3秒に短縮できる場合は、要求されるまで、汗をかいて2秒に短縮しないでください。

次に、簡単なチェックを行って、最適化しているクエリが論理的に正しいことを確認します。ばかげているように聞こえますが、実行速度の遅いクエリについてアドバイスを求められた回数はわかりません。たまに間違った答えが返されていることがわかりました。そして、結局のところ、クエリのデバッグは、速度を上げることにもなります。

特に、説明プランで「デカルト結合」というフレーズを探してください。そこにそれが表示されている場合、意図しないデカルト座標の参加を見つけた可能性は非常に高いです。意図しないデカルト結合の通常のパターンは、FROM句がコンマで区切られたテーブルをリストし、結合条件がWHERE句にあることです。結合条件の1つが欠落していることを除いて、Oracleはデカルト結合を実行する以外に選択肢がありません。大きなテーブルでは、これはパフォーマンスの低下です。

クエリが論理的に正しいEXPLAIN PLANにデカルト結合を表示することは可能ですが、これを古いバージョンのOracleに関連付けます。

また、未使用の複合インデックスを探します。複合インデックスの最初の列がクエリで使用されていない場合、Oracleはインデックスを非効率的に使用するか、まったく使用しない可能性があります。例を挙げましょう。

クエリは次のとおりです。

select * from customers    
where
     State = @State
     and ZipCode = @ZipCode

(DBMSはOracleではなかったため、構文が異なり、元の構文を忘れてしまいました)。

インデックスをざっと見ると、列(国、州、郵便番号)がこの順序で並んでいる顧客のインデックスがわかりました。クエリを次のように変更しました

  select * from customers
   where Country = @Country
      and State = @State
      and ZipCode = @ZipCode

オプティマイザはインデックスを有効に利用できたため、約6分ではなく約6秒で実行されました。私はアプリケーションプログラマーに、国を基準から除外した理由を尋ねたところ、これが答えでした。彼らはすべての住所の国が「USA」に等しいことを知っていたため、その基準を省略してクエリを高速化できると考えました。

残念ながら、データベース検索の最適化は、計算時間をマイクロ秒短縮することと実際には同じではありません。これには、データベース設計、特にインデックスの理解と、少なくともオプティマイザがどのように機能するかの概要が含まれます。

オプティマイザーをアウトスマートにしようとするのではなく、オプティマイザーとのコラボレーションを学ぶと、通常、オプティマイザーからより良い結果が得られます。

最適化のスピードを上げて頑張ってください!

7
Walter Mitty

あなたはロリポップのあいまいな終わりを手に入れました。

大量の追加情報と経験がなければ、説明プランを調べて、最適なパフォーマンスを下回っている原因を特定する方法は、単独では絶対にありません。クエリのチューニングを10ステップのプロセスに減らすことができれば、自動化されたプロセスによって行われます。これを効果的にするために理解する必要があるすべての事項をリストにしようとしていましたが、それは非常に長いリストになります。

私が考えることができる唯一の短い答えは...あなたが推測するよりもはるかに多くのバイトを通過している計画のステップを探すことです。次に、その数を減らす方法について考えます...インデックスまたはパーティション分割を使用します。

真剣に、コストベースのOracleFundementalsに関するジョナサンのルイスの本を入手してください

Oracleデータベースアーキテクチャに関するTomKyteの本を入手し、森の中で数週間キャビンを借りてください。

6
Mark Brady

これは膨大な専門分野です(別名ブラックアート)。

私が一般的に採用しているアプローチは次のとおりです。

  1. 問題のSQLステートメントを実行します。
  2. 実際の計画を取得し(dbms_xplanを検索)、
  3. 推定行数(カーディナリティ)と実際の行数を比較します。大きな違いは、修正する必要のある問題を示します(インデックス、ヒストグラムなど)
  4. プロセスの一部を高速化するためにインデックスを作成できるかどうかを検討します(通常、概念的には最初に計画を実行する必要があると考えている場合)。いくつかのインデックスを試してください。

データベースに要求している内容のコンテキストで、さまざまなインデックスのO()の影響を理解する必要があります。これは、Bツリー、ハッシュテーブルなどのデータ構造を理解するのに役立ちます。次に、機能し、プロセスを繰り返すインデックス。

Oracleがインデックスを使用しないと決定した場合は、INDEX()ヒントを適用して新しいプランを確認します。コストは選択したプランよりも高くなります-これがインデックスを選択しなかった理由です。ヒント付きの計画は、インデックスが良くない理由についての洞察につながる可能性があります。

4
WW.