データベース更新Windowsアプリケーションは、特定の1回限りの更新のプロセスの一部として、2つのデータベース間で一部のデータを転送する必要があります。データを移動する仲介者としてXMLを選択しました。
このプロセスは、ソースから行のチャンクをXMLとして選択することで機能します。XMLはアプリケーションを介してターゲットサーバーに渡され、そこでグローバル一時テーブルに細断されます。 (ソースデータベースとターゲットデータベースは2つの異なるインスタンス上に存在できます。)このプロセスは、必要なすべてのデータがターゲットインスタンスの一時テーブルに存在するまで繰り返されます。最後に、一時テーブルのレコードが実際のターゲットデータベーステーブルに統合されます。
私たちが抱えている問題は、一部の状況では、2番目のチャンクが非常に遅く、CPU使用率が非常に高く、まったく機能しないことです。ホスティング環境では問題を再現できますが、開発やQAでは再現できません。一部のクライアントもこの問題を抱えています。そのうちの1人は夜通し稼働させ、翌朝18(!)時間稼働した後、最終的にそれを殺しました。その場合、どれだけ進んだかわかりません。 〜2時間待った後、ホスティングで2番目のチャンクを通過できません。
これは、最初のチャンクのステートメントバッチです。
SET NOCOUNT ON;
DECLARE @src xml;
SET @src = CAST(@P1 AS xml);
SELECT
n.x.value(N'field1[1]', 'uniqueidentifier') AS field1,
n.x.value(N'field2[1]', 'smallint') AS field2,
... (8 more fields of various types) ...
INTO [##target_2994] /*******/
FROM @src.nodes('Rows[1]/Row') n(x);
そして、これは問題である2番目以降のチャンクのバッチです。
SET NOCOUNT ON;
DECLARE @src xml;
SET @src = CAST(@P1 AS xml);
INSERT INTO [dbo].[##target_2994] /*******/
SELECT
n.x.value(N'field1[1]', 'uniqueidentifier') AS field1,
n.x.value(N'field2[1]', 'smallint') AS field2,
... (8 more fields of various types) ...
FROM @src.nodes('Rows[1]/Row') n(x);
これが私がこれまで見てきたことです:
SOS_SCHEDULER_YIELD
INSERT
ステートメント。sys.dm_io_virtual_file_stats
ターゲットtempdb
は、基本的にアイドルであることを示しているため、I/Oの問題ではありません。SET
オプションは、問題がある場合と問題がない場合で同じです。MAXDOP
は、どのサーバーにも設定されていません(最大= 4論理プロセッサー)。お客様の設定がよくわかりません。誰か他の見たいことを提案できますか?
*計算された式の名前は異なり、推定された行サイズの1つで1%未満の違いがありましたが、全体的なコストの見積もりを含め、その他はすべて同じでした。
- SQL.2008 SP1ではXML.nodes()を使用したINSERTステートメントは非常に非常に遅い で、接続時にログに記録される同様の問題があります。
SQL2008を使用して、ノードクエリを使用してXMLをシュレッダーする場合、SELECTを実行するだけでパフォーマンスが向上します。ただし、データをtable/temptable/tablevariableに挿入する場合、パフォーマンスが非常に低下します。
RedGateのSQL Compareなどを使用してデータベースを比較する
RedgateのSQLデータ比較のようなものを使用してテーブルのデータを比較する
スキーマが同一でデータの違いが重要でない場合は、SQLインスタンスのプロパティを比較します。
違いが重要でない場合は、一時ファイルの使用状況を確認してください。
グローバルテーブルに挿入しています-作成した実際のテーブルに挿入してみてください。