4

次のクエリがあります。

  UPDATE t
  SET    UnitsSold = sub.UnitsSold,
  FROM   dbo.table1 t
         JOIN (SELECT s.CustomerKey,
                      s.WeekKey,
                      s.ProductKey,
                      Sum(s.UnitsSold)          AS [UnitsSold],
               FROM   dbo.table2 s
               WHERE  WeekKey >= 335
               GROUP  BY s.WeekKey,
                         s.CustomerKey,
                         s.ProductKey) AS sub
           ON sub.WeekKey = t.WeekKey
              AND sub.CustomerKey = t.CustomerKey
              AND sub.ProductKey = t.ProductKey

チャンピオンのように走ります。約2秒。次に、次の方法で動的にしようとします。

      DECLARE @StartWeekKey AS INT 
        SET @StartWeekKey = 335

  UPDATE t
  SET    UnitsSold = sub.UnitsSold,
  FROM   dbo.table1 t
         JOIN (SELECT s.CustomerKey,
                      s.WeekKey,
                      s.ProductKey,
                      Sum(s.UnitsSold)          AS [UnitsSold],
               FROM   dbo.table2 s
               WHERE  WeekKey >= @StartWeekKey
               GROUP  BY s.WeekKey,
                         s.CustomerKey,
                         s.ProductKey) AS sub
           ON sub.WeekKey = t.WeekKey
              AND sub.CustomerKey = t.CustomerKey
              AND sub.ProductKey = t.ProductKey

突然、それは超遅いです。

良いアイデアはありますか?

編集: Probalby はこれについて言及する必要がありましたが、これはストアド プロシージャに含まれています。

@StartWeekKey をパラメーターとして proc に追加すると、数秒で実行に戻ります。

4

2 に答える 2

1

この質問は以前にも何度か聞かれたようですが、一般的な答えは、統計に関係しているというものです。

試す:

UPDATE STATISTICS table_or_indexed_view_name

統計情報を最新のものにして、それが違いを生むかどうかを確認してください。

于 2012-06-04T18:59:22.473 に答える
0

異なるパラメータが非常に異なる分布を持ち、したがって異なる適切な計画を持っている場合、これは前例のないことではありません。発生する可能性があるのは、特定の値に対してクエリが実行された後、そのプランがキャッシュされ、別の値に対して不適切に再利用されることです。

これが事実である場合 (単なる推測です - クエリを実行して確認することはできません!)、以下を追加してみてください:

OPTION (OPTIMIZE FOR (@StartWeekKey UNKNOWN))

クエリの最後まで。


別の考え:WeekKey実際にはint? これはある種の大量の型変換の問題ですか?


これらを確認する方法はありません。私が軌道から何マイルも離れている場合は、役に立たない回答を削除できるようにお知らせください。

于 2012-06-04T19:03:39.493 に答える