在 SQL Server 中导入和解析大型 XML 文件(当“正常”方法相当慢时)
Posted
技术标签:
【中文标题】在 SQL Server 中导入和解析大型 XML 文件(当“正常”方法相当慢时)【英文标题】:Importing and parsing a large XML file in SQL Server (when "normal" methods are rather slow) 【发布时间】:2014-05-27 11:41:01 【问题描述】:我有一个大型 XML 文件,我需要将其导入并解析为 SQL Server 中的表格结构(“扁平化”)。 “大”是指大约 450 MB 的文件,包含多达 6-7 个嵌套级别和大量元素,大约 300 个。
我尝试使用 OPENXML 和 Xml.Nodes 解析文件。这两种方法都很慢。读取父元素及其嵌套孙子元素的部分查询需要几分钟甚至几十分钟才能运行。
我尝试使用 SQLXML 批量加载方法。不幸的是,我不能——因为文件结构不正确。有一个元素在逻辑上是父元素,但在物理上没有嵌套为父元素。
您认为唯一可行的解决方案是使用 .NET 还是 Java?我有什么遗漏吗?
在某种程度上,我更喜欢动态解决方案。我不希望 SQL Server 开发人员在他们无法控制/了解的程序性、已编译代码上进行中继——以防发生某些更改(在 XML 结构中)。
非常感谢。
【问题讨论】:
您是否将 XML 扁平化为表格结构? 确实如此。在某种程度上扁平化 - 取决于尚未完全确定的数据库结构。 我真的很想知道 OPENXML 和 XML.nodes 的执行时间分别是多少。 好的。似乎我错过了一些东西并以错误的方式使用了 Xml.Nodes() 。解决问题后,结果非常有趣。 OPENXML 查询为 4:42 秒。 0:47 用于 Nodes() 查询。哇,差别很大!无论如何,我构建了另一个查询,它从第 5 级获取一个“祖父”元素,从第 8 级获取很少的元素,从第 9 级获取很少的元素。我得到的 9155 个结果行花了 1:08 分钟。毕竟没有那么糟糕。仍然 - 提取整个 XML 可能有点慢?欢迎评论。 你可以堆叠cross apply nodes()
。在您的情况下,看起来对节点的第一次调用应该在第五级切碎,第二次在八级和最后的交叉应用应该在第九级。 ***.com/a/22216941/569436
【参考方案1】:
好的。我在 XML 数据列上创建了一个 XML 索引。 (现在只是一个主要的)。
之前需要约 4:30 分钟的查询现在需要约 9 秒!似乎使用适当的 XML Index 存储 XML 的表并使用 xml.nodes() 函数解析数据是一个可行的解决方案。
谢谢大家。
【讨论】:
【参考方案2】:由于您需要表格结构,您可以将 XML 转换为 CSV 文件(使用 this java 或 this .NET tool,甚至是 an XSLT tranformation),然后是 perform a bulk insert。
当然,这一切都取决于您的 XML 格式是否正确。
【讨论】:
谢谢圣地亚哥。我更喜欢使用可靠性更高的解决方案,甚至构建一个 .NET 应用程序。使用 csv 是自找麻烦。【参考方案3】:嗯,首先我真的不明白你为什么要使用 OpenXml 来加载文件。我很确定这样做会在内部触发一大堆根据 OpenXml ISO 标准的有效性测试。
但是 - Xml.Nodes() (我假设这意味着加载数据的 DOM 方式) - 是迄今为止加载和解析 Xml 数据最慢的方式。考虑使用 XmlReader 或类似的 SAX approach。我确实知道这篇文章是 2004 年的 - 但它仍然很好地解释了这些内容。
【讨论】:
好的。所以你是说为了获得良好的性能我必须放弃 SQL Server 的 XML 引擎(和 SQL 代码)并编写 .NET 代码? (之后将其集成到 CLR 等中......) 好吧,您确实说过您正在考虑编写一个 .Net 应用程序,但也许我误解了 :-)。但我确实学到了一些新东西——在你发帖之前我从未听说过 SQL Server 中的 OPENXML 关键字,所以我显然误解了 /that/ 部分。以上是关于在 SQL Server 中导入和解析大型 XML 文件(当“正常”方法相当慢时)的主要内容,如果未能解决你的问题,请参考以下文章