インデックスシークが正しい行数を推定でき、ソート演算子が推定できないのはなぜですか?


11

次のような述語の関数を使用するクエリがあります。

commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)

40000行のcommentTypeにフィルター処理されたインデックスがあり、クエリを実行すると、インデックスシークの推定行数は非常に正確(約11K)ですが、次のステップ(ソート演算子)では、統計を完全に無視し、フィルターされたインデックスの行の総数を推定するだけです。

なんでこんなことが起こっているの?私はsargabilityの基本を知っており、正気を期すために、dateaddを実際の日付(2014-01-01)と実際の日付で置き換えてテストしました...ソートは行数を正しく推測し始めました...

なぜこれが起こっているのですか、どうすれば修正できますか?決まった日を渡すことはできません...


DATEADD(month,datediff(month,0,getdate()) - 13,0)私には意味がありません。これで何をしようとしていますか?改善/簡略化できるでしょうか?
Daniel Hutmacher

2
@Daniel 13か月前の月初めです。
アーロンバートランド

1
また、現在使用しているSQL Serverのバージョン(?)を反映するように質問を編集してください。そのためにタグを使用します。
Daniel Hutmacher

DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))何か違いがあるか試してみてください。
Daniel Hutmacher

にフィルタリングされていないインデックスがある場合(commentType, commentDate)、そこではより良い動作をしますか?フィルター処理されたインデックスが、計画のさまざまな時点で推定を誤って報告することがあります。フィルターされたインデックスの総数を報告することで見積もりはかなり外れたように見えますが、実際には計画が間違って表示されているのです。
Rob Farley

回答:


9

DATEDIFF引数の2つを交換する推定機能のバグのため、あなたの推定は間違っていると思います。私はこれについてここで話します:

回避策は、DATEDIFF(2008+)を使用せずに13か月前の最初の日を計算することです。

DATEADD(MONTH, -13, DATEADD(DAY, 1-DATEPART(DAY,GETDATE()), CONVERT(DATE, GETDATE()));

私はないんだけど、正(私はフィルタのインデックスをテストしていません見積もりに取り組むこと、そして私は、ソートが実際にやってか、なぜそれが計画および/またはクエリの残りの部分なしに異なる推定値を持っているかわからないんだけど)。

マイクロソフトが推奨する修正はTF 4199を使用することですが、ここでそれを行う必要があるかどうかはわかりません。

もう1つのオプションは、使用しているSQL Serverのバージョンが最新のSP / CUであることを確認することです。これは、次のKB記事で修正されていると主張しているためです(ただし、TF 4199を使用する必要があります)。あなたが2014年以上でない限り):

この修正は、次のビルドで入手できます。

  • 2005 SP3 CU 15(> = 9.00.4325 AND <= 9.00.4999)
  • 2005 SP4 CU 2(> = 9.00.5259)
  • 2008 SP1 CU 13(> = 10.00.2816.00 AND <= 10.00.3999)
  • 2008 SP2 CU 3(> = 10.00.4279.00 AND <= 10.00.5499)
  • 拡張による2008 SP3&SP4(> = 10.00.5500)
  • 2008 R2 CU 7(10.50.1777.0)
  • 2008 R2 SP1 CU 3(> = 10.50.2769.0 AND <= 10.50.3999)
  • 拡張により2008 R2 SP2&SP3(> = 10.50.4000)
  • 拡張により、2012、2014、2016(> = 11.0)

(次回SELECT @@VERSIONは、質問の結果を含めてください。)

KB記事では、DATEDIFFが行数を過小評価する可能性があるとありますが、これはシナリオで発生していることとは逆です。これは、修正が適用されないという意味ではありません。データと見ている範囲に応じて見積もりがどちらの方向にも進む可能性があるため、KB記事の表現は不正確だと思います。

上記の私のブログ投稿では、2014年以降はスワップが発生しないことが確認されています。安全のために、私はおそらくあなたの述語からDATEDIFFを破棄し、別の方法を使用して範囲の開始を計算します。4199を過剰に使用したり、動的SQLを使用して不良スワップを防止したりすることはお勧めしません。


助けてくれてありがとう !私はあなたの提案を試みました、そして計画は変わりました。これは、前にあったかです:s16.postimg.org/t5j6o1yed/fix_wrong.pngこれは私があなたによって私のDateDiff関数を変更した後、それがどのようにある:postimg.org/image/5f725rj83は、 私はあなたが私を与えたすべてのURLを読んでするつもりです。乾杯。
MrKudz 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.