web-dev-qa-db-ja.com

このXMLプランフラグメントをどのように解釈しますか?

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プランのみです)

2
mustaccio

私自身の質問に答えるために、私の最初の理解は正しかった: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スタイルシート

1
mustaccio