内部結合のカーディナリティ推定問題


13

行の推定が非常に間違っている理由を理解するのに苦労しています、ここに私の場合があります:

単純な結合-SQL Server 2016 sp2を使用(sp1と同じ問題)、dbcompatiblity = 130。

select Amount_TransactionCurrency_id, CurrencyShareds.id 
from CurrencyShareds 
    INNER JOIN annexes ON Amount_TransactionCurrency_id = CurrencyShareds.Id 
option (QUERYTRACEON 3604, QUERYTRACEON 2363);

SQLは1行を推定しますが、107131であり、ネストされたループを実行することを選択します(planへのリンク)。CurrencySharedsの統計が更新された後、見積もりは問題なく、マージ結合が選択されます(新しいプランへのリンク)。CurrencySharedsに1つのレコードが追加されるとすぐに、統計が「古く」なり、sqlが誤った推定に戻ります。

この単純なクエリについてはあまり心配しませんが、これは大きなクエリの一部に過ぎず、これはドミノの始まりです...

1つの行を100レコードテーブルに追加すると、このような損傷が発生するのはなぜですか?カーディナリティ推定トレースの出力を調べると、この警告***WARNING: badly-formed histogram ***が表示されますが、このトピックに関する詳細は見つかりませんでした。

ここに、カーディナリティ推定からの完全な出力が出力されます:

Begin selectivity computation
Input tree:

LogOp_Join

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

ScaOp_Comp x_cmpEq

ScaOp_Identifier QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id

ScaOp_Identifier QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id

Plan for computation:

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1 *** WARNING: badly-formed histogram ***

Selectivity: 4.59503e-018

Stats collection generated:

CStCollJoin(ID=3, CARD=1 x_jtInner)

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

End selectivity computation

Estimating distinct count in utility function

Input stats collection:

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

Columns to distinct on:QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id

Plan for computation:

CDVCPlanLeaf

0 Multi-Column Stats, 1 Single-Column Stats, 0 Guesses

Covering multi-col stats id: 7

Using ambient cardinality 107131 to combine distinct counts:

5

Combined distinct count: 5

Result of computation: 5

Estimating distinct count in utility function

Input stats collection:

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

Columns to distinct on:QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id

Plan for computation:

CDVCPlanUniqueKey

Result of computation: 100

そして、CurrencySharedsの統計を更新すると、「形式が正しくないヒストグラム」が変更され、カーディナリティが正しく計算されます。

Plan for computation:

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1

Selectivity: 0.01

Stats collection generated:

CStCollJoin(ID=3, CARD=107131 x_jtInner)

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

End selectivity computation

そして、この「[CurrencyShareds] .ids with id 1の統計からのID」の統計情報と、ヒストグラムに関する警告が表示されます。

Name                                                                                                                             Updated              Rows                 Rows Sampled         Steps  Density       Average key length String Index Filter Expression                                                                                                                                                                                                                                                Unfiltered Rows      Persisted Sample Percent
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- ------------------------
PK_CurrencyShareds_Id                                                                                                            May 23 2018 10:43PM  98                   98                   75     1             8                  NO           NULL                                                                                                                                                                                                                                                             98                   0

(1 row affected)

All density   Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0,01020408    8              Id

(1 row affected)

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406464   0             1             0                    1
119762190797406466   1             1             1                    1
119762190797406468   1             1             1                    1
119762190797406470   1             1             1                    1
119762190797406472   1             1             1                    1
119762190797406474   1             1             1                    1
119762190797406476   1             1             1                    1
119762190797406478   1             1             1                    1
119762190797406480   1             1             1                    1
119762190797406482   1             1             1                    1
119762190797406484   1             1             1                    1
119762190797406486   1             1             1                    1
119762190797406488   1             1             1                    1
119762190797406490   1             1             1                    1
119762190797406492   1             1             1                    1
119762190797406494   1             1             1                    1
119762190797406496   1             1             1                    1
119762190797406498   1             1             1                    1
119762190797406500   1             1             1                    1
119762190797406502   1             1             1                    1
119762190797406504   1             1             1                    1
119762190797406506   1             1             1                    1
119762190797406507   0             1             0                    1
478531702587687680   0             1             0                    1
478531702591881728   0             1             0                    1
478531702591881729   0             1             0                    1
478531702591881984   0             1             0                    1
478531702591881985   0             1             0                    1
478531702596076032   0             1             0                    1
478531702596076033   0             1             0                    1
478531702596076288   0             1             0                    1
478531702600270336   0             1             0                    1
478531702600270592   0             1             0                    1
478532235583062528   0             1             0                    1
478532235583062784   0             1             0                    1
478532235587256832   0             1             0                    1
530792464911467264   0             1             0                    1
530792464924049920   0             1             0                    1
530792464924050176   0             1             0                    1
530792464928244224   0             1             0                    1
530792464928244480   0             1             0                    1
530792464932438528   0             1             0                    1
530792464932438784   0             1             0                    1
530792464936632832   0             1             0                    1
530792464936632833   0             1             0                    1
530792464936633088   0             1             0                    1
530792464940827136   0             1             0                    1
530792464940827392   0             1             0                    1
530792464949216000   2             1             2                    1
530792464953410048   0             1             0                    1
530792464953410304   0             1             0                    1
530792464957604352   0             1             0                    1
530792464957604353   0             1             0                    1
530792464957604608   0             1             0                    1
530792464961798656   0             1             0                    1
530792464961798912   0             1             0                    1
530792464965992960   0             1             0                    1
530792464965993216   0             1             0                    1
530792464965993217   0             1             0                    1
530792464970187264   0             1             0                    1
530792464970187265   0             1             0                    1
530792464970187520   0             1             0                    1
530792464974381568   0             1             0                    1
530792464974381824   0             1             0                    1
530792464974381825   0             1             0                    1
530792464978575872   0             1             0                    1
530792464978575873   0             1             0                    1
530792464978576128   0             1             0                    1
867420708903354880   0             1             0                    1
867420708903355136   0             1             0                    1
867420708903355137   0             1             0                    1
960876568220042240   0             1             0                    1
976385263448130048   0             1             0                    1
977302121709864192   0             1             0                    1
977955748426318592   0             1             0                    1

2番目のインデックスの情報:

Name                                                                                                                             Updated              Rows                 Rows Sampled         Steps  Density       Average key length String Index Filter Expression                                                                                                                                                                                                                                                Unfiltered Rows      Persisted Sample Percent
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- ------------------------
IX_FK_Amount_TransactionCurrency                                                                                                 May 21 2018  3:29PM  107204               107204               5      0             16                 NO           NULL                                                                                                                                                                                                                                                             107204               0

(1 row affected)

All density   Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0,2           8              Amount_TransactionCurrency_id
9,32801E-06   16             Amount_TransactionCurrency_id, Id

(2 rows affected)

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406475   0             160           0                    1
119762190797406478   0             867           0                    1
119762190797406481   0             106           0                    1
119762190797406494   0             105742        0                    1
119762190797406496   0             329           0                    1

回答:


10

ヒストグラムに基づいて、2017 CU6で問題を再現できました。あなたが何か間違ったことをしているとは言いません。むしろ、カーディナリティの推定に問題があります。行を挿入する前に取得するものは次のとおりです。

ここに画像の説明を入力してください

最終的なカーディナリティの推定値は、行を挿入した後にかなり低下します。

ここに画像の説明を入力してください

ここに非常に単純な再現があるので、私のフィードバックは、製品フィードバック提出するか、Microsoftでサポートチケットを開くことです。サンプルデータで機能するいくつかの回避策を見つけることができましたが、そのうちの1つが受け入れられる可能性があります。

  1. に一意のインデックスを削除しCurrencyShareds.Idます。一意のインデックスがないと、再現が機能しません。テーブルは小さいので、インデックスがなくてもうまくいくかもしれません。もちろん、それを維持する非常に良い理由があるかもしれません。
  2. 結合の結果を一時テーブルに具体化します。質問に基づいて、このステップで妥当な推定値を取得して、より大きなクエリがうまく機能するようにすることが重要です。一時テーブルは、それを実現する1つの方法です。
  3. レガシーCEを使用します。問題を再現することはできません。もちろん、これはクエリの残りの部分に悪影響を与える可能性があります。
  4. 愚かなコードでクエリオプティマイザーをだます。たとえば、私のテストでは、次の書き換えがうまく機能します。

select Amount_TransactionCurrency_id, CurrencyShareds.id
from CurrencyShareds 
INNER JOIN annexes
ON Amount_TransactionCurrency_id % 9223372036854775809 = CurrencyShareds.Id % 9223372036854775809

CEがヒストグラムの代わりに密度を使用しているように見えるため、これが機能すると思われます。他の同様の書き直しでも同じ効果があります。クエリのタイプが今後も引き続き機能するという保証はありません。そのため、Microsoftに連絡して、いつか問題の修正がリリースされた製品に反映される可能性を高める必要があります。


8

わかりました、今私はそれを理解することを望みます-それでこの私たちのケース

与えられた

  1. 〜100行の参照テーブル(CurrencyShareds)、ただしIDは大きく、最小値、最大値は大きく異なります-最小:119,762,190,797,406,464対最大:977,955,748,426,318,592
  2. あなたはIX_FK_Amount_TransactionCurrencyリストの5つのidをそのヒストグラムを見ることができます- - 、何が重要であるCurrencySharedにシンプルなFKを持っていますが、ほんの数通貨が使用されているテーブル(附属書)のみ他のものが使用されていないとして、これらの「低」のIDを。

すべての統計が最新の場合

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1

Selectivity: 0.01

この場合、結合について計算された選択性は、100 * 107,131 * 0.01 = 107,131のように良好です。

通貨共有の統計が最新でない場合、

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1 *** WARNING: badly-formed histogram ***

Selectivity: 4.59503e-018

選択性は劇的に低下するため、結合の推定行数は1です。

ヒストグラムが変化するとき

高いIDのCurrencySharedを参照する単一の行をアネックスに追加すると、IX_FK_Amount_TransactionCurrencyのヒストグラムが次のように変更されます。

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406475   0             173           0                    1
119762190797406478   0             868           0                    1
119762190797406481   0             107           0                    1
119762190797406494   0             105745        0                    1
119762190797406496   0             330           0                    1
119762190797406618   0             1             0                    1
119762190797406628   0             1             0                    1
977955748426318623   0             1             0                    1

このヒストグラムを使用すると、問題はなくなり、currencysharedsに新しい行を追加しても、カーディナリティの推定値が劇的に低下することはありません。

何故ですか?

私はこれがsql2014 +で粗いヒストグラム推定アルゴリズムがどのように機能するかを疑っています。この素晴らしい投稿https://www.sqlshack.com/join-estimation-internals/に基づいて推測しています

粗いヒストグラム推定は新しいアルゴリズムであり、一般的な概念の観点からもあまり文書化されていません。ヒストグラムを段階的に整列させる代わりに、最小および最大のヒストグラム境界のみで整列させることが知られています。この方法では、CEのミスが少なくなる可能性があります(ただし、これは単なるモデルであることを覚えているため、常にではありません)。

すべてを明確にするために-なぜ通貨共有にこのような奇妙なIDがあるのですか?

それは非常に単純です-idはグローバルに一意であり、タイムスタンプ(snowflakeに基づく実装)に一部基づいています。最も一般的な通貨は、数年前のアプリケーションの開始時に追加されたもので、実際に実際に使用されるのはこれらの少数のみです。そのため、ヒストグラムには「低」IDの通貨のみが存在します。

問題はテスト環境で表面化し、自動化された一部のテストでテスト通貨の追加が開始され、一部のクエリの実行が長くなったりタイムアウトしたりしました...

問題を修正するには?

これらの参照テーブルの統計を頻繁に更新します(他の同様の参照データテーブルと同様の問題がある可能性があります)-これらのテーブルは小さいので、統計の更新は問題ではありません

学んだ教訓

  • 最新の統計が重要です!!!
  • 古いプレーンID列はこれらの問題を引き起こしません:)

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