2011-01-24 6 views
4

私はこの質問があまりにも明白ではないことを願っています...私はすでに実行計画の解釈に関する多くの良い情報を見つけましたが、答えが見つからないという質問が1つあります。SQL実行計画は、スキーマまたはデータ、またはその両方に基づいていますか?

スキーマのみ、または現在データベースに格納されている実際のデータに基づいて、計画(具体的には相対CPUコスト)はありますか?

私の製品のデータベースでインデックスが必要な場所を分析しようとしていますが、フィールド内にある製品のデータ量に近い独自のテストシステムで作業しています。私は、インデックスを追加した後に実際にCPUコストが少し上がったような奇妙なものがあるのを見ています。

私は計画を実行するためにSQL Server 2005とManagement Studioを使用しています

+1

特にデータベースはありますか?彼らはすべて物事を全く同じように扱うわけではありません。 –

答えて

4

これは、スキーマとデータの両方に基づいています。スキーマは、どのインデックスが利用可能であるかを指示します。

回答は、使用しているDBMS(指定していない)に応じて少々変わる可能性がありますが、インデックスが役立つかどうかを知るためにインデックスに関する統計をすべて保持しています。索引が1000行を900の別個の値に分割する場合、それは使用するのに適した索引です。インデックスが1000行に3つの異なる値しか得られない場合、それは実際にはselectiveではありませんのであまり役に立ちません。

1

スキーマとデータの両方。

クエリの各ステップで返された行数を近似するためにクエリプランを作成するときに、統計情報を考慮します(さまざまな種類の結合などのパフォーマンスに影響する可能性があるため)。

これの良い例は、この状況ではテーブルスキャンを実行する方が高速であるため、非常に小さなテーブルでインデックスを使用するのは面倒ではありません。

1

私はすべてのRDBMSシステムについて話すことはできませんが、Postgresはクエリプランを構築する作業の一環として推定テーブルサイズを具体的に使用しています。例として、テーブルに2つの行がある場合、そのテーブルを使用するJOINの部分に対して順次テーブル・スキャンを選択できますが、10000+の行がある場合は、インデックスまたはハッシュ・スキャンを使用することもできます)実際には、VIEWの見積もりサイズがないため、実際のテーブルの代わりにVIEWを結合することで、Postgresの貧弱なクエリプランを引き起こすことは可能でした。

Postgresがクエリプランを構築する方法の一部は、設定ファイル内の調整可能パラメータに依存します。 Postgresがどのようにクエリプランを構築するかについての詳細は、Postgres Webサイトを参照してください。

+0

一般に、VIEWは計画前にSQLクエリで展開されるため、そのために必要な統計情報がありません。 – araqnid

0

SQL Serverの場合、最終的な実行計画には多くの要因があります。基本的なレベルでは、統計は非常に大きな役割を果たしますが、データに基づいていますが、必ずしもすべてのデータに基づいているわけではありません。統計も常に最新ではありません。インデックスを作成または再構築する場合、統計はデータのFULL/100%サンプルに基づいている必要があります。ただし、自動統計更新のサンプルレートは100%よりもはるかに低いので、実際にデータの大部分を代表しない範囲をサンプリングすることは可能です。操作の推定行数も、表の行数またはフィルター操作の統計に基づく役割を果たす。したがって、古くなった(または不完全な)統計では、テーブル内のいくつかの行がインデックスを完全に無視するようになる可能性があるので、オプティマイザが最適ではないプランを選択する可能性があります。別の回答で述べたように、よりユニークな(すなわち、選択的)、データがより有用であることを示す。ただし、統計情報を保持する唯一の保証された列は、索引の先頭(または「左端」または「最初」)の列であることに注意してください。 SQL Serverは、他の列の統計情報を収集することもできます(一部のIndexesではなく、AutoCreateStatistics DBオプションが設定されている場合はデフォルトで設定されます)。

また、外部キーの存在は、これらのフィールドがクエリ内にあるときにオプティマイザを助けることができます。

しかし、質問で考慮されていない領域の1つは、クエリ自体の領域です。わずかに変更されたが同じ結果を返すクエリは、根本的に異なる実行計画を持つことができます。理想的には、(操作がある読んで心に留めておく、今

WHERE DATEADD(DAY, -1, field) < GETDATE() 

:など、

LIKE '%' + field 

または関数内のフィールドをラップ:使用してインデックスの使用を無効にすることも可能です)を使用すると、索引を高速化することができますが、DML操作(INSERT、UPDATEおよびDELETE)は、索引のメンテナンスが必要になるほど遅くなります(CPUおよびディスクI/Oが増えます)。

最後に、コストの「推定された」CPUなどの値は、必ずしも信頼されるとは限りません。より良いテストは、以下を行うことです。

SET STATISTICS IO ON 
run query 
SET STATISTICS IO OFF 

「論理読み取り」に焦点を当てます。論理読み込みを減らすと、パフォーマンスが向上するはずです。

最終的には、インデックスとクエリ自体の両方に関してパフォーマンスチューニングを行うために、プロダクションにある程度近いデータセットが必要です。

0

のOracle仕様:

述べたコストは、実際の推定実行時間ですが、それはブロックが読み込みのために予定時間に関係している対策のやや難解な単位で与えられます。いずれにしても、オプティマイザによるすべての見積もりが100%完璧(決してそうでない)でない限り、計算されたコストは実行時間についてはあまり言わないことに気づくことが重要です。

オプティマイザは、クエリに適用できる変換/ヒューリスティックを決定する際に、スキーマを多く使用します。 xplansを評価する際に多くの問題では、スキーマのもののいくつかの例:

  • 外部キー制約(テーブルelimiationのために使用することができます)
  • パーティション(データの全体の範囲を除外する)
  • ユニーク制約(インデックス対ユニーク例えば範囲スキャン)NULL可能列に
  • ないNULL制約(抗合流する(していないと使用できません)
  • データタイプ(型変換、専門的な日付の算術演算)
  • Materializ (集計に対してクエリを書き換えるため)されたビュー
  • 寸法階層(関数従属性を決定するために)
  • チェック制約(それはコストを下げる場合は、制約が注入される)
  • インデックスタイプ(Bツリー(?インデックス内)、ビットマップ、
  • )関数は、ベース、接合された列の順序(a = 1 {A、B} =レンジ・スキャンで、{B、A} =スキャンまたはFFSをスキップ)

推定のコア実際のデータ(または調理済み)に収集された統計を使用することに由来します。統計は、表、列、索引、パーティションなどのために収集されます。

以下の情報が収集される。

  • Nr個の行のテーブル/パーティションに
  • 平均行/
  • 番号(フルスキャン、ハッシュ結合、ソート、一時テーブルを原価計算のために重要)コル長
  • colの格別の値
  • colの最小値/最大値(などの無制限の範囲の条件を助けます))

...データをフィルタリングするときに返される予想される行数/バイトのnrを推定するのに役立ちます。この情報は、使用可能なアクセス・パスと結合メカニズムを判別するために使用され、SQL照会からの実際の値が統計と比較されます。

さらに、「良い」または魅力的なインデックスが完全なテーブルスキャンとどのようになるかに影響を与える物理的な行の順序もあります。索引の場合、これは「クラスタリング係数」と呼ばれ、行の順序と索引エントリの順序がどれくらい一致するかの尺度です。

2

SQL Serverはコストベースの100%オプティマイザです。他のRDBMSオプティマイザは、通常、コストベースとルールベースの組み合わせですが、SQL Serverの方がコストがかかります。ルールベースのオプティマイザは、たとえばと言うことができます。FROM句のテーブルの順序によって、結合テーブルの駆動テーブルが決定されます。 SQL Serverにはこのようなルールはありません。 SQL Statement Processingを参照してください:

SQL Serverクエリオプティマイザが コストベース・オプティマイザです。それぞれの可能な 実行プランには、使用される計算量が という点で、関連するコスト があります。クエリオプティマイザ は、可能なプランを分析し、 は最低コストのものを選択してください。 見積もりコスト。いくつかの複雑なSELECT ステートメントには、実行計画が数千種類ある可能性があります。このような場合、 クエリオプティマイザはすべて の組み合わせを分析しません。代わりに、 は複雑なアルゴリズムを使用して の実行計画を見つけます。 は、合理的に最小値 に近いです。

SQL Serverクエリオプティマイザは、リソースコストが最も低い実行プラン のみを選択しません。 は、 という結果を返すプランを、 リソースで合理的なコストでユーザーに選択し、その結果を と最も速く返します。たとえば、 クエリを並列処理すると、通常、 というリソースが連続的に処理されるよりも多く使用されますが、クエリは速く完了します。 SQL Serverオプティマイザは、 パラレル実行プランを使用して、サーバー上の負荷が悪影響を受けない場合は の結果を返します。

クエリオプティマイザは、それ がテーブルまたはインデックスから 情報を抽出するための 異なる方法のリソースコストを推定 分布統計に依存しています。 ディストリビューションの統計情報は、 の列とインデックスに対して保持されます。これらは、 の特定のインデックスまたは列の値の選択性を示します。 の例では、車を表す表で 多くの車は同じメーカーです ですが、各車には固有の車両 識別番号(VIN)があります。 VINのインデックス は、製造元の インデックスよりも選択的です。 インデックスの統計情報が最新でない場合、 クエリオプティマイザは、 のテーブルの現在の状態を最適化することができません。 のインデックス統計情報を最新に保つ方法の詳細については、 Using Statistics to Improve Query Performanceを参照してください。

関連する問題