web-dev-qa-db-ja.com

高速XML、低速XML

データベース更新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);

これが私がこれまで見てきたことです:

  • これはブロッキングの問題ではありません。待機統計は99%ですSOS_SCHEDULER_YIELDINSERTステートメント。
  • sys.dm_io_virtual_file_statsターゲットtempdbは、基本的にアイドルであることを示しているため、I/Oの問題ではありません。
  • すべてのデータには固定幅の列しかないため、非常に長いテキストフィールドはありません。
  • データチャンクサイズは現在25,000行であり、これを下げる可能性がありますが、同じデータセットのいくつかを問題なくテストしたため、違いは説明されていません。転送する必要のある最大のテーブルは、725,000行であり、正常にテストされました。
  • クエリプランは問題ありと問題なしで同じです(XMLのファイル比較を行いました)。
  • セッションのSETオプションは、問題がある場合と問題がない場合で同じです。
  • バージョンは要因ではないようです。ホスティングは2008 R2 SP1 Enterprise x64です。 2005 SP4 + Standard x64で2008 R2 SP1 + Developer x86まで問題なくテストしました。問題のあるお客様は、2008 RTM/SP1 Standard/Enterprise x64(これまでのところ)です。
  • 仮想化は要因ではないようです。ホスティングとQAは仮想化されています。開発者は部分的に仮想化されています。問題を抱えている顧客は身体的です。 MAXDOPは、どのサーバーにも設定されていません(最大= 4論理プロセッサー)。お客様の設定がよくわかりません。
  • 2つのデータベースが同じサーバー上と異なるサーバー上にある場合でも、違いはありません。
  • TSボックスで更新アプリケーションを実行しても、ローカルで実行しても違いはありません。
  • Tempdbデータベースの設定は同じです。
  • インスタンスとデータベースの照合順序は同じです。
  • ターゲットサーバーのtempdbの互換性レベルを90に変更しても、効果はありませんでした。 ( あたりのマークの答え
  • インスタンス構成に大きな違いはありません。 ( 神保の答え

誰か他の見たいことを提案できますか?

*計算された式の名前は異なり、推定された行サイズの1つで1%未満の違いがありましたが、全体的なコストの見積もりを含め、その他はすべて同じでした。

3
Jon Seigel

- SQL.2008 SP1ではXML.nodes()を使用したINSERTステートメントは非常に非常に遅い で、接続時にログに記録される同様の問題があります。

SQL2008を使用して、ノードクエリを使用してXMLをシュレッダーする場合、SELECTを実行するだけでパフォーマンスが向上します。ただし、データをtable/temptable/tablevariableに挿入する場合、パフォーマンスが非常に低下します。

4

RedGateのSQL Compareなどを使用してデータベースを比較する

RedgateのSQLデータ比較のようなものを使用してテーブルのデータを比較する

スキーマが同一でデータの違いが重要でない場合は、SQLインスタンスのプロパティを比較します。

違いが重要でない場合は、一時ファイルの使用状況を確認してください。

グローバルテーブルに挿入しています-作成した実際のテーブルに挿入してみてください。

0
Jimbo