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


12

高密度の2つの列があるが、これらの列が独立していない状況を考えています。

定義

これが、テスト目的で作成したテーブルの定義です。

CREATE TABLE [dbo].[StatsTest](
    [col1] [int] NOT NULL,  --can take values 1 and 2 only
    [col2] [int] NOT NULL,  --can take integer values from 1 to 4 only
    [col3] [int] NOT NULL,  --integer. it has not relevance just to ensure that each row is different
    [col4]  AS ((10)*[col1]+[col2])  --a computed column ensuring that if two rows have different values in col1 or col2 have different values in col4 
) ON [PRIMARY]

データ

実験のデータは次のとおりです

col1    col2    col3    col4
1       1       1       11
1       2       2       12
1       2       3       12
1       3       4       13
1       3       5       13
1       3       6       13
1       4       7       14
1       4       8       14
1       4       9       14
1       4       10      14
2       1       11      21
2       1       12      21
2       1       13      21
2       1       14      21
2       2       15      22
2       2       16      22
2       2       17      22
2       3       18      23
2       3       19      23
2       4       20      24

ステップ1:col1によるフィルタリング

SELECT * FROM StatsTest WHERE col1=1

予想どおり、Query Optimizerは正確な行数を推測します。 実際の行数= 10および推定行数= 10

ステップ2:col2によるフィルタリング

SELECT * FROM StatsTest WHERE col2=1

繰り返しますが、完全な推定値があります。

実際の行数= 5および推定行数= 5

ステップ3:col1およびcol2によるフィルタリング

SELECT * FROM StatsTest WHERE col1=1 AND col2=1

ここで、推定は実際の行数に近いものではありません。 実際の行数= 1および推定行数= 3,53553

問題は、クエリアナライザーの暗黙では、col1とcol2が独立しているが、独立していると仮定していることです。

ステップ4:col4によるフィルタリング

SELECT * FROM StatsTest WHERE col4 = 11

col4は計算列であり、定義された方法に従ってcol1 = 1であり、col2 = 1col4 = 11と同等であるため、col4 = 11 でフィルター処理して、ステップ3のクエリと同じ結果を得ることができます。ただし、 、予想どおり推定は完璧です。

実際の行数= 1および推定行数= 1

結論/質問

¿この人為的で洗練されていないソリューションは、独立した2つ以上の列によるフィルタリングを処理する場合に正確な推定を達成するための唯一の利用可能なオプションですか?¿計算列と計算列によるフィルターは、実際の精度を得るために厳密に必要ですか?

sqlfiddleの


col1 / 2にいくつかのインデックスを作成しないのはなぜですか?
LowlyDBA 14

実際、私はしましたが、機能しなかったのでここに含めませんでした。ヒストグラムのための最初の列のみが考慮さおよび密度は、値の異なる数を考慮していないそれらの分布である
JGA

回答:


15

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

本当の多次元ヒストグラムではありません

この人為的で洗練されていないソリューションは、2つ以上の独立していない列によるフィルタリングを処理するときに正確な推定を達成するための唯一の利用可能なオプションですか?

SQL Serverは「複数列」統計をサポートしますが、最初の名前付き列のヒストグラムに加えて平均密度(相関)情報のみをキャプチャします。それらは等価比較にのみ有用です。

平均密度情報は詳細をキャプチャしないため、2列の統計オブジェクトの値のペアに対して同じ選択性が得られます。場合によっては、複数列の統計で十分であり、何もないよりも優れている場合があります。複数列の統計は、複数列のインデックスに基づいて自動的に構築されます。

SQL Serverのバージョンによっては、フィルター処理されたインデックスフィルター処理された統計を使用できる場合もあります

-- Filtered statistics example
CREATE STATISTICS stats_StatsTest_col2_col1_eq_1
ON dbo.StatsTest (col2)
WHERE col1 = 1;

CREATE STATISTICS stats_StatsTest_col2_col1_eq_2
ON dbo.StatsTest (col2)
WHERE col1 = 2;

または、インデックス付きビュー(独自のインデックスと統計をサポートできる)を構築できます。インデックス付きビューは、DATE_CORRELATION_OPTIMIZATIONデータベース設定の背後にあるメカニズムであり、テーブル間の相関にあまり使用されない機能ですが、質問の精神に適用されます。

計算列と計算列によるフィルターは、実際の精度を得るために厳密に必要ですか?

唯一の方法ではありません。既に説明したことに加えて、計算列の正確なテキスト定義を指定することもでき、オプティマイザーは通常、計算列の統計と一致させます。

複数列の相関について行われた仮定を変更するトレースフラグもあります。また、SQL Server 2014の既定の相関関係の仮定(新しいカーディナリティ推定器が有効になっている)は、独立から指数バックオフに変更されました(詳細はこちらこちら)。最終的には、これは単なる別の仮定です。それは多くの場合良くなり、他の場合は悪くなります。

優れた実行計画を取得するために、カーディナリティ推定の正確な精度は必ずしも必要ではありません。さまざまなパラメーター値に再利用できるプランを生成することと、特定の実行には最適であるが再利用されないプランを生成することとの間には常にトレードオフがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.