2012-01-04 10 views
1

高価な計算の値(不変のXML列のxquery)を取り込むテーブルがあります。実動環境への展開をスピードアップするために、私はテストサーバーで値をあらかじめ計算し、BCPを使ってファイルに保存しています。私は最初の二つの文は、秒以内に完了する管理スタジオでスクリプトを実行すると連続して実行するとSQLクエリが遅くなりますが、別々に実行するとすばやく実行します。

-- Lots of other work, including modifying OtherTable 

CREATE TABLE FOO (...) 
GO 

BULK INSERT FOO 
FROM 'C:\foo.dat'; 
GO 

-- rerun from here after the break 

INSERT INTO FOO 
    (ID, TotalQuantity) 
SELECT 
e.ID, 
SUM(e.Quantity) as TotalQuantity 
FROM (select 
    o.ID, 
    h.n.value('TotalQuantity[1]/.', 'int') as TotalQuantity 
FROM dbo.OtherTable o 
    CROSS APPLY XmlColumn.nodes('(item/.../salesorder/)') h(n) 
WHERE o.ID NOT IN (SELECT DISTINCT ID FROM FOO) 
) as E 
GROUP BY e.ID 

を次のように

私のスクリプトですが、最後の文が完了するまでに4時間かかります。私のfoo.datは管理スタジオレポート(0 row(s) affected)を計算して以来、OtherTableに行が追加されていないためです。

数分後にクエリの実行を取り消し、最後のクエリだけを選択して別々に実行すると、5秒以内に完了します。

注目すべき事実:

  • OtherTableは20万行とXmlColumn内のデータが含まれているかなり大きな、合計テーブルサイズ〜3ギガバイト
  • あるFOOテーブルは何でし1.3M行

を取得おそらく違いを生み出すだろうか?
管理スタジオで暗黙的なトランザクションがオフになっています。私はそれぞれのステートメントがそれ自身のトランザクションで実行されることを理解できる限りです。

更新:
私が最初-- rerun from here after the breakまでスクリプトを選択して実行すると、私は実行をキャンセルして再試行するまで、そしてちょうど最後のクエリを選択して実行し、それはまだ遅いです。これは、スクリプト内の前のコードと "一緒に"実行することの影響を排除し、同じクエリが最初の実行では遅く、2番目の実行では速くなります(他のすべての条件が同じで実行されます)。

+0

実行計画に違いはありますか?最後の声明では4時間かかりますが、実際の計画ではなく、見積もり計画を見ることができます。 –

+0

"数分後にクエリの実行をキャンセルし、最後のクエリだけを選択して実行すると、5秒以内に完了します。" - あなたはselectを単独で実行していますか?空のfooに結果を挿入するか、結果を空白のfooに挿入していますか?fooは主にBCPプロセスまたはOtherTableの挿入から1.3M行を取得しますか? –

+0

@MarkBannister私がキャンセルしたポイントから同じスクリプトを続行しています。すべての1.3M行は一括挿入に由来します(これは '' 0行が影響を受けたものです) ')を示します。 –

答えて

0

なぜそれが助けられたのか分かりませんが、代わりに最後のクエリをleft outer joinに書き直して突然実行が15ミリ秒になりました。

INSERT INTO FOO 
    (ID, TotalQuantity) 
SELECT 
e.ID, 
SUM(e.Quantity) as TotalQuantity 
FROM (select 
    o.ID, 
    h.n.value('TotalQuantity[1]/.', 'int') as TotalQuantity 
FROM dbo.OtherTable o 
INNER JOIN FOO f ON o.ID = f.ID 
    CROSS APPLY o.XmlColumn.nodes('(item/.../salesorder/)') h(n) 
WHERE f.ID = null 
) as E 
GROUP BY e.ID 
2

おそらく異なる実行計画です。 Slow in the Application, Fast in SSMS? Understanding Performance Mysteriesを参照してください。

+0

私はhttp://www.fulltablescan.com/index.php?/archives/149-Viewing-the-Execution-Plan-of-a-Running-Query-in-SQL-Server.htmlを使用しました。遅い実行クエリの実行計画を取得しますが、私が見る限り、2回目に同じ実行計画を使用しています。残念ながら、各部分の実行カウントを取得することはできません(私は、私が4時間待たなければ、完全な実行計画を得るためにクエリを一晩実行させようとします。 –

+0

さらに、実行計画は、Management Studioからの2つの同一の呼び出しの間で、他のアクティビティがなくても変更されるのはなぜですか? –

+0

'なぜ実行計画が変更されるのですか? ':stats –

1

新しく作成されたFooテーブルで統計情報が完全に間違っている可能性はありますか? SQL Serverが最初にクエリを実行するときに統計を自動的に更新する場合、2回目の実行では最新の統計から作成された実行計画が作成されます。

バルク挿入直後の統計情報(STATS_DATE機能あり)を確認し、長時間実行されたクエリをキャンセルした後に再度確認するとどうなりますか?クエリがキャンセルされたにもかかわらず、統計情報が更新されましたか?

この場合、一括挿入後のUPDATE STATISTICSFooに役立ちます。

+0

クエリが実行された後、FOOテーブルのPKの統計日はNULLです。可能な修正のように聞こえる。しかし、私は、クエリを「LEFT OUTER JOIN」に書き換えることによって、妥当な実行時間を得ることができました。 –

関連する問題