SQL Server 2008 R2によって作成されたクエリプランを見ていますが、正しく解釈されているかどうかわかりません。例:
<RelOp NodeId="2" PhysicalOp="Sort" LogicalOp="Sort" EstimateRows="1" EstimateIO="0.0112613"
EstimateCPU="0.000100822" AvgRowSize="822" EstimatedTotalSubtreeCost="1.06489" Parallel="0"
EstimateRebinds="0" EstimateRewinds="0">
...
<MemoryFractions Input="0.5" Output="1" />
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="10190123" ActualRebinds="1" ActualRewinds="0" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
そして
<RelOp NodeId="6" PhysicalOp="Index Seek" LogicalOp="Index Seek" EstimateRows="1" EstimateIO="1"
EstimateCPU="0.0502411" AvgRowSize="24" EstimatedTotalSubtreeCost="1.05024" TableCardinality="4.93715e+009"
Parallel="0" Partitioned="1" EstimateRebinds="0" EstimateRewinds="0">
...
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="10190123" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
具体的には、EstimateRows="1"
とActualRows="10190123"
を見ると、オプティマイザーが処理される行数を誤って推定しているのではないかと思います。その後、ソートに設定された行セットが過小評価されると、ソートが大幅に流出する可能性があります。
編集:
問題のクエリは次のようになります
select whatever from mytable
where integer_column1 > 848484884 and
integer_column1 < 949494949 and
another_int_col in (5, 8, 15, 20)
ここで、integer_column1
のカーディナリティは数百万単位であり、another_int_col
のカーディナリティは数十(一種のフラグ)です。 (integer_column1, another_int_col)
には、一意ではない、クラスター化されていないインデックスがあります。更新された統計が存在する場合でも、オプティマイザーはそのインデックスのヒストグラム/密度ベクトルを使用できるのだろうか。
私の推論は理にかなっていますか?
(実際のシステムや管理コンソールにはアクセスできません。XMLプランのみです)
私自身の質問に答えるために、私の最初の理解は正しかった:EstimateRows="1"
とActualRows="10190123"
の間の不一致は、(コメント提供者によって示唆されたように)古い統計によって引き起こされた不正確なオプティマイザー推定の指標でした。統計が更新されると、質問のノード6に対応するプランのノードは次のようになります。
<RelOp NodeId="25" PhysicalOp="Index Seek" LogicalOp="Index Seek"
EstimateRows="1.25676e+007" EstimateIO="23.8363" EstimateCPU="1.78132" AvgRowSize="24"
EstimatedTotalSubtreeCost="25.6176" TableCardinality="4.94087e+009" Parallel="1"
Partitioned="1" EstimateRebinds="0" EstimateRewinds="0">
...
<RunTimeInformation>
<RunTimeCountersPerThread Thread="2" ActualRows="3457399" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="8" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="1" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="7" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="5" ActualRows="8053198" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="3" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="6" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="4" ActualRows="0" ActualEndOfScans="1" ActualExecutions="1" />
<RunTimeCountersPerThread Thread="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="0" />
</RunTimeInformation>
問題はXMLプラン表現で直接確認できますが、グラフィカル表現が必要な場合は、SQL Server Management Studio、SQL Sentry Plan Explorer、さらにはWindowsを必要としない無料のツールがあります。 StackOverflowユーザーJustinによって作成されたXSLスタイルシート 。