5

私はNOAAの現在の観測XML(例:ワシントンDC)を使用しており、4000以上のステーションのファイルをSQL Server2008R2テーブルに細断処理しています。多くの異なるアプローチを試した後、私は前進しているアプローチを持っています。

この質問は、さまざまな方法間のパフォーマンスに関するものであり、最も重要なのは、なぜそれがそれほど劇的なのかということです。

最初の試み

C#での作業では、Linq to XMLを使用してすべてのファイルを解析し、結果のレコードをLinqtoSQLを使用してデータベースに書き込みました。このためのコードは予測可能であるため、私はあなたを退屈させません。

linqを使用してEntityFrameworkに書き換えても効果はありませんでした。

その結果、アプリケーションは1時間以上実行され、1600程度のファイルしか処理されませんでした。速度が遅いのは、LinqtoSQLとLinqtoEntitiesの両方が、レコードごとに挿入と選択を実行した結果です。

2回目の試行

まだC#で​​作業しているので、オンラインで利用できる一括挿入メソッドを使用して高速化を試みました(例:Linq-to-SQLを使用した挿入の高速化-パート1)。

最初の試みよりも著しく速いが、それでも遅い。

この時点で、ストアドプロシージャを使用してXMLシュレッダーを処理し、ファイルを1つのXML文字列に連結してラッパータグを追加するC#コードを挿入するようになりました。

3回目の試行

これに似たSQLServerのXMLクエリを使用する(@xmlはxmlファイルです)[メモリから]:

select credit = T.observation.value('credit[1]', 'varchar(256)')
       ,... -- the rest of the elements possible in the file.
from @xml.nodes('wrapper') W(station)
    cross apply W.station.nodes('current_observation') T(observation)

15分間実行し、250件程度のレコードを処理してキャンセルしました。

4回目の試行

OpenXMLを使用するようにクエリを変更しました。

declare $idoc int

exec sp_xml_preparedocument @idoc output, @xml

select Credit
       ,... -- the rest of the elements
from openxml(@idoc, '/wrapper/current_observations', 2)
    with (
        Credit varchar(256) 'credit'
        ,...) -- the rest of the elements

exec sp_xml_removedocument @idoc

これにより、4000以上のレコードすべてが10秒で処理されました。かなり受け入れられます。

方法の違いは予想していましたが、それほど劇的な違いはないと思いました。

だから私の質問は単純に、

「なぜ、異なる方法の間でパフォーマンスにこのような劇的な違いがあるのですか?」

最初の3つを間違って使用していたことが示されてとてもうれしいです。

4

3 に答える 3

2

XQueryオプションを高速化するために実行できる可能性のあることの1つは、クロス結合を回避することです。

XMLがどのように見えるかわかりません-ワシントンDCのサンプルには単一のノードしか含まれていません-しかし、XMLにa<wrapper>とその中のリストが含まれていると仮定すると<current_observation>、XQueryを最適化して次のように読み取ることができます。

select 
    credit = T.observation.value('credit[1]', 'varchar(256)')
    ,... -- the rest of the elements possible in the file.
from 
    @xml.nodes('wrapper/current_observation') T(observation)

これは、テストで見た速度よりもはるかに高速に動作するはずです。

これを試す時間があれば、元のXQUeryとOPENXMLソリューションに対して、この変更されたアプローチがどのように積み重なるかを知ることに最も興味があります。

于 2012-07-15T07:53:36.513 に答える
1

クエリで親軸('..')を使用していないことを確認できますか?これにより、パフォーマンスが低下する可能性があります。text()アクセサーを追加することもできます。これにより、以下のようにパフォーマンスも向上します。

select
o.c.value('(credit/text())[1]', 'varchar(max)'),
--...
from @xml.nodes('wrapper/current_observation') o(c)
于 2012-07-15T21:39:35.213 に答える
0

テキストアクセサーを試しましたか?これは、型指定されていないXML(SQL ServerにXSDが関連付けられていない)にのみ適用されますが、4,096レコードを含む6MB xmlファイルに対して再現性が15〜20%向上しました。

また、クエリが10〜12秒で実行されていることがわかったので、43秒でまだ少し不思議に思っています。使用しているSQLServerのバージョン/サービスパックは何ですか?SQL 2005でテーブル変数に挿入するときに問題があったことを覚えていますが、これは修正されたと思いました。

于 2012-07-16T14:17:46.637 に答える