インデックスを作成するよりも統計を作成したほうがよいのはいつですか?


38

私は上の情報をたくさん発見したものを STATISTICS、次のとおりです。彼らは、彼らがクエリやインデックスから手動または自動で作成する方法を、維持、およびようにしていますか。しかし、私は見つけることができなかったいかなるに関するガイダンスや「ベストプラクティス」の情報それらを作成するには:インデックスからではなく、手動で作成されたSTATISTICSオブジェクトのほうがどのような状況にメリットがあるか。私は手動でフィルターされた統計を作成し、パーティション化されたテーブルのクエリを支援しました(インデックス用に作成された統計はテーブル全体をカバーし、パーティションごとではないためです-brillaint!)インデックスの詳細を必要とせず、インデックスを維持したり、ブロック/デッドロックの可能性を高めたりするコストも必要ありません。

@JonathanFiteはコメントで、インデックスと統計の違いについて言及しました。

インデックスは、テーブル自体とは異なる方法でソートされたルックアップを作成することにより、SQLがデータをすばやく見つけるのに役立ちます。統計は、クエリを満たすために必要なメモリ/労力をSQLが判断するのに役立ちます。

主に質問を明確にするのに役立つからです。

どのようにこのことを知っている(または上の任意の他の技術的な情報はないものを Sとどのように行動しての性質に関連sをSTATISTICS)助けを決定するとき選択するCREATE STATISTICS以上CREATE INDEXの関連が作成されますインデックスを作成するときに、特に、STATISTICSオブジェクトを?どのようなシナリオでは、よりよい持っていることによって提供されることになるだけ STATISTICS情報をしていないインデックスを持ちますか?

可能な場合、STATISTICSオブジェクトがに比べてより適しているシナリオの実用例があると、非常に便利INDEXです。


私は視覚的な学習者/思考者であるため、最適なタイミングを判断するのに役立つ可能性のある手段として、STATISTICSINDEXes の違いを並べて確認すると役立つと思いSTATISTICSました。

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

以下は、これを探しているときに見つけたリソースで、同じ質問をしているものの、回答がありませんでした。

SQL Serverインデックスと統計

SQL Serverの統計に関する質問

統計学。複数列のヒストグラムは可能ですか?

**明確にするために、私はこれに対する答えがなく、実際にインターウェブで奇妙に欠けている情報のように見えるものを提供するために、できれば少数の人々からフィードバックを得たいと思っています。


1
インデックスは、テーブル自体とは異なる方法でソートされたルックアップを作成することにより、SQLがデータをすばやく見つけるのに役立ちます。統計は、クエリを満たすために必要なメモリ/労力をSQLが判断するのに役立ちます。
ジョナサンファイト

@JonathanFiteそのコメントをありがとう。私の質問にそれを組み込みました:)。
ソロモンラッツキー

@JonathanFiteのコメントに従って、統計はアドホックシステム/テーブル/クエリパターンのパフォーマンスを向上させるのに最適であり、インデックスは予測可能なクエリパターンに適しているようです。これは、発言というよりも質問のようなものです。
デイブ

回答:


19

あなたは質問を中心に展開します-統計を作成するのとインデックスを作成する(統計を作成する)のは良いことです。

私のSQLサーバー内部のメモ(SQLSkillsクラス-IE1およびIE2)およびSQLサーバー内部の本から、以下は私の限られた理解です:

SQL Serverの統計は、インデックスキー値と通常の列値に関する重要な情報を含むシステムオブジェクトに他なりません。

SQL Serverは、コストベースのモデルを使用して、「十分な」実行計画を可能な限り迅速に選択します。カーダニリティの推定(クエリ実行の各ステップで処理される行数の推定)は、クエリの最適化において最も重要な要素であり、結合戦略、メモリ許可要件、ワーカースレッドの選択、およびデータにアクセスする際のインデックスの選択に影響します。

SQL Serverは、大きなnoを推定すると非クラスター化インデックスを使用しません。KEYまたはRIDのループアップ操作が必要になるため、インデックス(および列)の統計を保持します。これは、このような推定に役立ちます。

統計情報には2つの重要なことがあります:

  1. ヒストグラムには、左端の統計(インデックス)列のデータ分布に関する情報のみが保存されます。また、キー値の複数列密度に関する情報も保存します。そのため、本質的に、ヒストグラムには左端の統計列のみのデータ分布が格納されます。

  2. SQL Serverは、テーブルサイズに関係なく、最大200ステップのヒストグラムを保持します。各ヒストグラムステップでカバーされる間隔は、テーブルが大きくなるにつれて長くなり、大きなテーブルの「精度が低く」なります。

    インデックスの選択性は密度に反比例するメトリックであることに注意してください。つまり、列の値が一意になるほど、選択性が高くなります。

特定のクエリがあまり頻繁に実行されない場合、インデックスではなく列レベルの統計を作成することを選択できます。列レベルの統計は、クエリオプティマイザーがより優れた実行プランを見つけるのに役立ちます。ただし、それらの実行プランは、関連するインデックススキャンのために最適ではありません。同時に、統計はデータ変更操作中にオーバーヘッドを追加せず、インデックスのメンテナンスを回避するのに役立ちます。このアプローチは、めったに実行されないクエリに対してのみ機能します。

参照:

注:Paul WhiteAaron Bertrandのような人がチャイムインして、あなたの良い質問にもっと色を付けることができます


「SQL Serverは、多数のKEYまたはRIDループアップ操作が必要になると推定した場合、非クラスター化インデックスを使用しません」それでは、QOは、インデックスとは関係なく、インデックスに基づく統計オブジェクトを使用できますか?つまり、インデックスが最適ではないが、先頭の列がクエリ内にある場合、統計は依然として関連しています。それで、それらは使用されますか?または、この情報は、インデックスが使用される可能性が低い場合があるかもしれないことを意味していますが、統計にはまだ値があるので、インデックスを作成する本当の理由はなく、統計を行うだけですか?
ソロモンラッツキー

8

データの量を制限したり、フィールドに基づいて正しいデータをすばやく取得したりする必要がある場合は、インデックスが必要だと思います。

オプティマイザーがデータの性質を理解して最適な方法で操作を実行できるようにする必要がある場合、統計が必要です。

私が理解したように、フィルタリングされた統計は、プランに大きな影響を与えるデータのスキューがある場合に役立ちます。たとえば、スタックオーバーフローでは、少数のユーザーが膨大な数の投稿を持っているため、ユーザーごとの平均投稿だけを使用することは実際には最良の推定ではありません。そのため、ユーザー名に基づいてuserIdのフィルター処理された統計を作成できます。SQLServerは、このユーザー名がクエリに含まれている場合、これが取得するユーザーIDであり、 postsテーブルのインデックス付きフィールドには、ヒストグラムが存在するため、そのIDを持つ大量の行があります。平均では、それを行うことはできません。


1
こんにちは。お返事ありがとうございます。だから、私は必要/したいと思うときに、オプティマイザは、よりよいデータの性質を理解し、まだいないデータまたはがより速くそれを取得したいことを制限すること、または「カバー」にクエリを、それを必要としますか?フィルター選択されたインデックスの例でも同じです。平均からエッジケースを取り除くという点であなたが言っていることは分かりますが、同じフィールドのフィルターされたインデックスよりフィルターされた統計の方が優れているのはなぜですか?これが私が達成しようとしている区別です。
ソロモンラッツキー

例のように、postsテーブルには存在しないため、ユーザー名にフィルター処理されたインデックスを作成できません。ユーザーIDに基づいて作成できますが、それはwhere句にはありません。
ジェームズZ

しかしUserIDWHERE?ではなくても、JOIN状態ではないでしょう。そして、それはフィルターされたインデックスを拾うのに十分ではないでしょうか?
ソロモンラッツキー

@srutzky最新バージョンではおそらくそうかもしれませんが、一般的に私はそれに依存しません...ほとんどの場合、述語は正確に一致する必要があります。彼らがこれを修正したかどうか忘れますが、ある時点で、フィルターWHERE BitColumn = 0選択されたインデックスは単純なクエリに対して選択されませんWHERE BitColumn <> 1。(そして、明確にするために、ビット列はNULL可能ではありませんでした。)IntColumn > 10一致しないなどの類似したケースがあったと思いますIntColumn >= 11
アーロンバートランド

次回誰かがプランを使用するときに、フィルター選択されたインデックスが適切ではなくなる可能性がある場合、フィルター選択されたインデックスは使用できません。フィルター選択されたインデックスを使用できる結合は考えられません。次回は値が適切ではない可能性があるため、変数でさえ使用できません。
ジェームズZ

4

70-461 Itzik Ben-Ganによるトレーニングブックから

統計を手動で作成する理由はいくつかあります。1つの例は、クエリ述語にクロスカラムリレーションシップを持つ複数のカラムが含まれている場合です。複数の列の統計は、クエリプランの改善に役立ちます。複数の列の統計には、単一列の統計では使用できないクロスカラム密度が含まれています。ただし、列がすでに同じインデックスにある場合は、複数列の統計オブジェクトがすでに存在するため、追加の列を手動で作成しないでください。


これを投稿してくれてありがとう。これは私の質問の一部に答えますが、まだ質問を開いたままにします:複数列の統計が必要な場合、なぜインデックスの代わりにSTATISTICSのみを作成しますか? ies)?
ソロモンラッツキー

1
Kinの説明は、あなたが何を求めているかをさらに説明すると思います。おそらく頻繁に挿入されるが、めったにクエリされないヒープでしょうか?
ケンタロウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.