SQL Server XML粉碎性能

Dav*_*ulp 5 xml performance sql-server-2008-r2

我正在使用NOAA当前的观察XML(例如:华盛顿特区),并将4000多个站点的文件粉碎成SQL Server 2008 R2表.在尝试了许多不同的方法后,我有一个我正在前进的方法.

这个问题是关于不同方法之间的表现,最重要的是它为什么如此激烈.

第一次尝试

在C#中工作,我使用Linq解析所有文件到XML,并使用Linq to SQL将结果记录写入数据库.这个代码是可以预测的,所以我不会厌烦你.

用linq重写实体框架没有帮助.

这导致应用程序运行了一个多小时,并且只处理了1600个左右的文件.缓慢是Linq to SQL和Linq to Entities执行插入并为每条记录选择的结果.

第二次尝试

仍然在C#中工作我试图通过使用在线提供的批量插入方法加快速度(例如:使用Linq-to-SQL加速插入 - 第1部分).

虽然比第一次尝试快得多,但仍然很慢.

此时,我转而使用存储过程来处理XML碎化,并使用C#代码将文件连接到一个XML字符串并添加包装器标记.

第三次尝试

使用类似于此的SQL Server的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)
Run Code Online (Sandbox Code Playgroud)

我让它运行了15分钟并取消了处理250条左右的记录.

第四次尝试

我更改了查询以使用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
Run Code Online (Sandbox Code Playgroud)

这在10秒内处理了所有4000多条记录!相当可以接受.

虽然我预计这些方法之间存在一些差异,但我并不认为这种差异会如此显着.

所以我的问题很简单,

"为什么不同方法之间的性能差异如此之大?"

我很高兴被证明我使用的是前3个错误.

mar*_*c_s 2

为了加速 XQuery 选项,您可以做的一件事是避免交叉连接。

我看不到您的 XML 是什么样子 - 华盛顿特区示例仅包含一个节点 - 但假设 XML 仅包含一个节点<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)
Run Code Online (Sandbox Code Playgroud)

这应该比您在测试中看到的速度快得多。

如果您有时间尝试这个 - 我最想知道这种修改后的方法如何与您原来的 XQUery 和解决方案相结合OPENXML