web-dev-qa-db-ja.com

自動サンプリングによる統計更新は密度ベクトルとヒストグラムを台無しにします

2200万件のレコードを含むテーブルがあります。

その列に一定の分布があったとしても、列の統計がかなりずれていることに気付きました。実際、すべての値が2回繰り返されています。

このシナリオを視覚化するために、別のテーブルの一意のIDごとに、チェックイン日とチェックアウト日(2つの異なるレコード)を持つテーブルを考えます。

これらはフルスキャンの統計です: Statistics with fullscan

これらは自動サンプリングによる統計です: enter image description here

なぜこの奇妙な行動なのか?正しいサンプリングレートを決定するための経験則はありますか、それともフルスキャンが必要ですか?一部の統計について、フルスキャンで統計更新ジョブを作成する必要がありますか?その場合、この種の処理が必要な統計はどのようにして知ることができますか?

追加情報:

  • その列には外部キー制約はありません
  • 列はnumeric(14,0) NULLです
6
Mattia Nocerino

なぜこの奇妙な行動なのか?

誰かが100万の整数の本をあなたに与え、10のサンプリングされた数値に基づいて全体の分布について推測するようにあなたに言ったと仮定します。受け取る10個のサンプリングされた数値は、1、1、125000、125000、250000、250000、375000、375000、500000、および500000です。1つの完全に妥当な推測は、1〜500000の範囲のペアで500000の一意の整数が含まれていることです。同様に有効な推測は、本に5つの一意の整数が含まれ、各整数が200000回存在することです。データの分布については、SQL Serverは、後者の解釈により近いサンプルに基づいてデータについて推論を行っています。ヒストグラムを作成するアルゴリズムは、サンプリングされたすべてのデータ分布に対して適切に機能しません。これには、一意の整数がそれぞれ2回表示されるものも含まれます。 SQL Server 2017で説明した問題を簡単に再現できました。

正しいサンプリングレートを決定するための経験則はありますか、それともフルスキャンが必要ですか?

私が知っている唯一の経験則は、正しいサンプリングレートが、許容可能なクエリまたはシステムパフォーマンスを提供するサンプリングレートと少なくとも等しいことです。私はDBAが100%のサンプリングレートを使用してその分析を回避していることを発見しました。これは、それほど大きくないテーブルの場合、完全に合理的なショートカットです。

テーブルを、基になる2つのテーブルに基づいて作成された 更新可能なビュー に置き換えることを検討できます。基礎となる各テーブルには、データの半分が含まれる可能性があります。 SQL Serverは、テーブルごとに個別の統計オブジェクトを構築します。統計を微調整しなくても、パフォーマンスが向上する場合があります。これが特定のシナリオに適したアプローチであるかどうかはわかりません。

一部の統計について、フルスキャンで統計更新ジョブを作成する必要がありますか?

それはあなたが説明している問題の一般的な解決策です。別のオプションとして、SQL Server 2016 SP1 CU4では、STATISTICSコマンドに PERSIST_SAMPLE_PERCENT キーワードが導入されています。これを使用して、SQL Serverに、自動統計更新がトリガーされるたびに常にこの列の特定のレートで統計をサンプリングするように指示できます。非同期統計の更新が無効になっている場合は、列を使用するクエリのクエリのコンパイル時間が長くなる場合があることに注意してください。

その場合、この種の処理が必要な統計はどのようにしてわかりますか?

通常の答えは、許容できないクエリパフォーマンスについてワークロードを監視し、どのクエリに統計の問題があるかを判別し、統計の変更でこれらの問題を修正することです。プロアクティブになりたい場合は、プロダクションのコピーの統計を分析することを検討できます。最初に、データベース上のすべての関連する列のサンプル統計を取得し、すべての密度ベクトルをテーブルに保存します。そのためには、DBCC SHOW_STATISTICS WITH DENSITY_VECTORを使用できます。次に、FULLSCANを使用して同じ統計をすべて更新し、それらの密度ベクトルも保存します。次に、密度ベクトルを比較して、差異が最大の統計オブジェクトを見つけることができます。これはすべての統計の問題を見つけるわけではありませんが、この質問で観察したものと同様のものを見つけます。

4
Joe Obbish

列の統計のフルスキャン更新を実行すると、SQL Serverは列の正確な性質を理解できますが、既定のスキャンは、テーブルの行の「統計的に有意な」サンプルを調べます。テーブルでは、行の「統計的に有意な」サンプルにより、データの全体像が不完全になります。

異常な値の分布を持つテーブルの場合、完全なスキャン統計の更新は、ほとんどの場合、はるかに正確なヒストグラムになります。全体的に「最適な」選択肢はありません。デフォルトのサンプルレートは、mostテーブルの統計更新パフォーマンスとクエリパフォーマンスのバランスに役立ちます。

列に含まれるデータを理解することで、フルスキャンがより良い統計につながるかどうかを判断できます。

経験則として、私は常に毎晩または毎週実行される統計再スキャンジョブをセットアップし、I/Oを最小限に抑えるためのいくつかの要件を除いて、それらの統計のFULLSCAN更新を実行するようにそのジョブをセットアップします。私が作成するジョブは、「x」回の更新/挿入/削除を受信し、「x」時間内に統計更新がなかった更新テーブルのみです。アクティビティが少ない期間にスケジュールに従ってジョブを実行すると、ほとんどの場合、SQL Serverがアクティビティが多い期間に統計の更新を実行できなくなります。

masterのストアドプロシージャとSQL Serverエージェントジョブを介して統計を更新する方法を示すブログ投稿を書きました: http://www.sqlserver.science/maintenance/statistics-update-job /

1
Max Vernon