【问题标题】:Speeding up Import of XML into SQL server加快将 XML 导入 SQL 服务器的速度
【发布时间】:2020-06-19 17:22:56
【问题描述】:

您好,我有一个有效的 Powershell 脚本,可以将我经常使用的大型 XML 文件导入我的 SQL 服务器。

文件太大而无法直接导入 (4.5Gb),因此 Powershell 脚本用户 @Tomalak 帮助我很多,目前工作正常,但仍需要 2 多个小时才能运行。我正在尝试寻找更快的选择。

Link to previous post on generating the script

我正在尝试加快这个过程,并且最近正在考虑将 XML 拆分为更小的文件并循环使用 SQL 的批量插入,也可能拆分文件并使用 Powershell 但并行运行。

批量插入在插入数据时会比 powershell 运行得更快吗?此外,我不认为它的插入花费了更多的时间来循环并从 XML 文件中提取数据。

谁能给我指出一个不同的方向或建议一种可以更快地处理这项任务的方法?

对所有选项开放。

感谢您的宝贵时间。

【问题讨论】:

  • “批量插入在插入数据时会比 powershell 运行得更快吗?” - 你比任何人都更有资格回答这个问题:) 尝试并衡量差异
  • 我会试一试,我只是在最后一个小时内才设法拆分文件,并且更多地询问我是否按照正确的思路思考。我用谷歌搜索了很多,但我想我会问,因为有很多方法可以完成任何任务,
  • 我会说这绝对是一个值得的实验 - 我很幸运能够通过生成巨大的 INSERT 语句并提交这些语句而不是以编程方式尝试逐行导入来加速从平面文件中进行类似导入.
  • 我目前正在编写一个批量插入脚本,所以会大胆尝试并报告。

标签: sql-server xml powershell parallel-processing bulkinsert


【解决方案1】:

在进行导入之前对 XML 执行一些优化可能会使您受益。 XML 文件本质上是臃肿的。减少标签名称的长度会对文件大小(从而解析性能)产生巨大影响。例如,将“ProductID”更改为“P”。它甚至不必是文件中的每个标签,只要是更常见的标签即可。我已经能够将 XML 文件大小减少 50-80% 之间的任何地方。当然,您必须更改导入以读取新字段名称。

您可以通过将一部分 XML 拉入编辑器并全局搜索/替换标签名称来进行试验,以了解它对文件大小的影响。

【讨论】:

  • 谢谢,我会进一步加快速度,我最终拆分文件并使用 buk insert 导入它们并使用 openrowset 返回数据
  • 我会用详细信息更新我上面的帖子。我的工作大约减少了 2 小时。只是在大文件上运行一些测试并以新的方式与 poweshell 记录数字。
【解决方案2】:

好的,所以使用@Matthius R. jessen 的建议,我将我的主文件分成 500000 个块

使用此软件分割文件Firstobject XMl editor(free) 可以从命令行调用,并且能够加载一个非常大的 xml 文件,而其他一些软件则难以解决。

然后我用它从拆分文件中提取数据。

USE [OPENXMLTesting]
GO

DROP TABLE [dbo].[XMLwithOpenXML]
GO

SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[XMLwithOpenXML](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [XMLData] [xml] NULL,
    [LoadedDateTime] [datetime] NULL,
PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

USE OPENXMLTesting
GO

INSERT INTO XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK 'C:\Scripts\ImportTest\piece1.xml', SINGLE_BLOB) AS x;

SELECT * FROM XMLwithOpenXML

将数据插入 SQL 的总时间 34 秒

然后使用

从元素中查询我想要的主要数据的结果
USE OPENXMLTesting
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT Product_ID, path, Updated, Quality, Supplier_id, Prod_ID, Catid, On_Market, 
Model_Name, Product_View, HighPic, HighPicSize, HighPicWidth, HighPicHeight, 
Date_Added
FROM OPENXML(@hDoc, 'root/file')
WITH 
(
`Product_ID [int] '@Product_ID',
path [varchar](100) '@path',
Updated [varchar](50) '@Updated',
Quality [varchar](50) '@Quality',
Supplier_id [int] '@Supplier_id',
Prod_ID [varchar] '@Prod_ID',
Catid [int] '@Catid',
On_Market [int] '@On_Market',
Model_Name [varchar](250) '@Model_Name',
Product_View [int] '@Product_View',
HighPic [varchar] '@HighPic',
HighPicSize [int] '@HighPicSize',
HighPicWidth [int] '@HighPicWidth',
HighPicHeight [int] '@HighPicHeight',
Date_Added [varchar](150) '@Date_Added'
)


EXEC sp_xml_removedocument @hDoc
GO

这一步57秒检索root的子元素及其属性的总时间

然后,我需要从父元素中取回元素的子元素以及引用的 Prod_ID,以便稍后对数据执行连接。

我跑了

USE OPENXMLTesting
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT Prod_ID, M_Prod_ID
FROM OPENXML(@hDoc, 'root/file/M_Prod_ID',2)
WITH 
(
Prod_ID [varchar] (50) '../@Prod_ID',
M_Prod_ID [varchar] (50) '../M_Prod_ID'
)

EXEC sp_xml_removedocument @hDoc
GO

总共 32 秒

因此,总时间拉入并查询我想要的元素的 500,000 行,而其中的子元素花费了 2 分 3 秒。不是实际的插入,而是选择,因此可能需要多一点才能将数据放入数据库,但不会太多。

然后,我使用旧的 Powershell 脚本尝试了相同的操作,结果花费了 6 分 39 秒

如果处理整个文件,现在大约需要 32 分钟,而大约需要 2.5 小时,这是一个很大的改进。我现在需要做的就是编写一个脚本来遍历拆分文件并一个接一个地导入。

感谢大家的建议。我对结果很满意。之前我可以通过进一步清理 XML 来加快它的速度,但现在我对现在将要短得多的过程感到非常满意。

【讨论】:

  • 从SQL Server 2005 开始,最好使用基于w3c 标准的XQuery 语言来处理XML 数据类型。保留 Microsoft 专有的OPENXML 及其伙伴sp_xml_preparedocumentsp_xml_removedocument 只是为了向后兼容过时的SQL Server 2000。强烈建议重新编写SQL 并将其切换到XQuery。您可以就该主题提出单独的问题。
  • 好的,谢谢您的意见,我刚刚开始学习我在网上找到的教程。看起来我有一些新的工具要学习。我将进行更改并更新帖子。有什么推荐的教程或指南吗?
  • 您的帖子有2个问题:(1)如何将XML文件导入SQL Server。 (2)如何在SQL Server中查询XML数据类型列。最好将您的帖子分成 2 个问题。
  • 感谢您的指导和链接。我导入数据的方式是首选方式吗?还是您会建议一种不同的方法?
猜你喜欢
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 2017-03-04
相关资源
最近更新 更多