5

我正在使用 NOAA 当前的观察 XML(例如:Washington DC)并将 4000 多个站点的文件切碎到 SQL Server 2008 R2 表中。在尝试了许多不同的方法之后,我有了一个正在推进的方法。

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

第一次尝试

在 C# 中工作时,我使用 Linq to 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)

我让它运行了 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

这在 10 秒内处理了所有 4000 多条记录!完全可以接受。

虽然我预计这些方法之间会有一些差异,但我没想到差异会如此巨大。

所以我的问题很简单,

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

我很高兴被证明我使用了前 3 个错误。

4

3 回答 3

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)

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

如果您有时间尝试这个 - 我最感兴趣的是了解这种修改后的方法如何叠加 - 与您原来的 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

您是否尝试过文本访问器?相对于其中包含 4,096 条记录的 6MB xml 文件,我的重现提高了 15-20%,尽管这仅适用于无类型的 XML(SQL Server 中没有关联的 XSD)。

我还发现我的查询在 10-12 秒内运行,所以你的 43 秒仍然让我有些困惑。您使用的是什么版本/服务包的 SQL Server?我记得在 SQL 2005 中插入表变量时曾经出现过问题,但认为这已解决。

于 2012-07-16T14:17:46.637 回答