web-dev-qa-db-ja.com

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

行の推定がひどく間違っている理由を理解するのに苦労しています。これが私のケースです。

単純な結合-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であり、ネストされたループ( link to plan )を実行することを選択します。 CurrencySharedsで統計が更新された後、見積もりは正常に行われ、マージ結合が選択されます( 新しいプランへのリンク )。 CurrencySharedsにレコードが1つだけ追加されるとすぐに、統計は「古く」なり、SQLは誤った推定に戻ります。

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

100レコードのテーブルに1行追加すると、なぜこのような損傷が発生するのですか?カーディナリティ推定トレースの出力を調べると、次の警告が表示されます***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] .Id from stats with id 1"の統計情報にヒストグラムに関する警告が表示されます。

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
13
LeMaciek

わかりました。理解できたと思います。

与えられた

  1. 100行以下の参照テーブル(CurrencyShareds)ですが、IDは大きく、最小値、最大値は大きく異なります-最小:119,762,190,797,406,464対最大:977,955,748,426,318,592
  2. CurrencySharedへの単純なFKを持つテーブル(アネックス)ですが、通貨はほとんど使用されていません-IX_FK_Amount_TransactionCurrencyのヒストグラムには5つのIDがリストされています-重要なものonlyこれらの「低い」ID。他の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のように、結合に対して計算された選択性は問題ありません。

Currencysharedsの統計が最新でない場合、

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

このヒストグラムでは問題が解消され、新しい行をCurrencySharesに追加しても、カーディナリティの推定が大幅に低下することはありません。

何故ですか?

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

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

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

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

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

問題を解決するには?

これらの参照テーブルの統計を更新します(他の類似の参照データテーブルでも同様の問題が発生する可能性があります)-これらのテーブルは小さいため、統計の更新は問題ありません

学んだ教訓

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

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

enter image description here

行を挿入すると、最終的なカーディナリティの見積もりはかなり低下します。

enter image description here

ここにはかなり単純な再現があるので、 製品のフィードバックを送信 またはマイクロソフトでサポートチケットを開くことをお勧めします。サンプルデータを処理するいくつかの回避策を見つけることができましたが、そのうちの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に連絡して、ある日、問題の修正がリリースされた製品に組み込まれる可能性を高める必要があります。

10
Joe Obbish