5

多くのテーブル (10-11) にまたがるかなり複雑なストアド プロシージャをデバッグしようとしています。ツリーの一部で、推定された行数が実際の行数と大幅に異なることがわかりました。実際には 55,000 行が返されるのに、最悪の場合、SQL サーバーは 1 行が返されると見積もっています!

これがなぜなのかを解明しようとしています - すべての統計は最新であり、いくつかのテーブルで FULLSCAN を使用して統計を更新しました。ユーザー定義関数やテーブル変数は使用していません。私が見る限り、SQL サーバーは返される行数を正確に見積もることができるはずですが、数万回の RDI ルックアップを実行する場合の計画を引き続き選択します (1 回だけ実行すると予想される場合)。または 2)。

推定行数が大幅にずれている理由を理解するにはどうすればよいですか?

更新:計画を見て、特に疑わしいと思われる1つのノードを見つけました-それは、次のプレデケートを使用したテーブルのテーブルスキャンです。

status <> 5
AND [type] = 1
OR [type] = 2

この述語はテーブル全体を返します (630 行 - テーブル スキャン自体がパフォーマンスの低下の原因ではありません) が、SQL サーバーの推定行数はわずか 37 です。SQL サーバーは、これを使用して RDI に対していくつかのネストされたループを実行し続けます。ルックアップ、インデックス スキャン、およびインデックス シーク。これが私の大規模な誤算の原因でしょうか? より賢明な行数を見積もるにはどうすればよいですか?

4

4 に答える 4

8

SQL Server200各インデックスを次のデータで最大範囲に分割します (ここから):

  • RANGE_HI_KEY

    ヒストグラム ステップの上限を示すキー値。

  • RANGE_ROWS

    範囲内にある行の数を指定します (これよりも小さいRANGE_HI_KEYが、前の small よりも大きいRANGE_HI_KEY)。

  • EQ_ROWS

    と正確に等しい行数を指定しますRANGE_HI_KEY

  • AVG_RANGE_ROWS

    範囲内の個別の値ごとの平均行数。

  • DISTINCT_RANGE_ROWS

    この範囲内に個別のキー値がいくつあるかを指定します (以前のキーRANGE_HI_KEYRANGE_HI_KEYそれ自体は含みません)。

通常、入力された値のほとんどは に入りRANGE_HI_KEYます。

ただし、範囲内に入る可能性があり、これが分布の偏りにつながる可能性があります。

これらのデータを想像してみてください (とりわけ):

キー値 行数

1          1
2          1
3          10000
4          1

SQL Serverは通常、2 つの範囲を作成します: 1to34次の入力値までで、これらの統計が作成されます。

RANGE_HI_KEY  RANGE_ROWS  EQ_ROWS  AVG_RANGE_ROWS  DISTINCT_RANGE_ROWS
3             2           10000    1               2

、つまり を検索する場合、2行しかない1ため、インデックス アクセスを使用することをお勧めします。

しかし3、範囲内に入ると、統計は次のようになります。

RANGE_HI_KEY  RANGE_ROWS  EQ_ROWS  AVG_RANGE_ROWS  DISTINCT_RANGE_ROWS
4             10002       1        3334            3

オプティマイザは3334、キーの行があり2、インデックス アクセスが高すぎると判断します。

于 2009-09-25T11:21:33.343 に答える
3

インデックスごとに保持する統計を使用します。

(索引付けされていない列で統計を作成することもできます)

データベース内のすべてのテーブルのすべての統計を更新するには (警告: 非常に大きなデータベースでは時間がかかります。DBA に確認せずに本番サーバーでこれを行わないでください...):

exec sp_msforeachtable 'UPDATE STATISTICS ?'

最もアクティブなインデックス (つまり、大量の INSERTS または DELETE) を再構築するための定期的にスケジュールされたジョブがない場合は、インデックスの再構築を検討する必要があります (上記と同じ警告が適用されます)。

exec sp_msforeachtable "DBCC DBREINDEX('?')"
于 2009-09-25T11:17:39.030 に答える
0

統計はすでに更新されているので、パラメーターのスニッフィングを排除しようと思います。

CREATE PROCEDURE xyz
(
    @param1 int
    ,@param2 varchar(10)

)AS

DECLARE @param_1 int
       ,@param_2 varchar(10)

SELECT @param_1=@param1
      ,@param_2=@param2

...complex query here....
...WHERE column1=@param_1 AND column2=@param_2....

go
于 2009-09-25T11:17:29.497 に答える
0

インデックスを再構築すると、誤った推定行値の問題が解決する場合があります

于 2010-08-04T18:57:25.920 に答える