【问题标题】:XML Transformation and SQL PerformanceXML 转换和 SQL 性能
【发布时间】:2016-03-22 08:01:38
【问题描述】:

我有一个场景,我编写了 100 多个程序,这些程序正在执行以下任务

  1. 加载 XML 文件
  2. 使用来自 XML 的数据进行操作
  3. 将数据存储或更新到表中

所有这些过程都包含临时表。这会影响 SQL Server 的性能。目前所有的程序都由计划的作业运行。这使服务器很忙。我正在寻找一些优化的方法来执行转换,这样它就不会影响 SQL 性能。我没有太多经验去做这件事。有什么线索可以实现吗?

这是我如何获取 XML 数据的代码

CREATE TABLE #XMLWithOpenXML([Id] [int] IDENTITY(1,1) NOT NULL, [XMLData] [xml] NULL)
CREATE TABLE #AllFiles  (Id INT IDENTITY, Subdirectory NVARCHAR(100), Depth INT, [File] INT)
CREATE TABLE #RowDetail (colone INT, ColTwo NVARCHAR(50), ColThree NVARCHAR(50), )

INSERT INTO #AllFiles 
EXEC xp_dirtree 'C:\XmlFiles',1,1
DELETE FROM #AllFiles  WHERE [file] = 0
DECLARE @Count AS INT, @FileName AS NVARCHAR(100), @Index AS INT, @Query AS NVARCHAR(4000)
SET @Index = 1
SELECT @Count = COUNT(*) FROM #AllFiles 
WHILE(@Index <= @Count)
BEGIN
    SELECT @FileName = Subdirectory FROM #AllFiles  WHERE Id = @Index
    SET @Query = 
    'INSERT INTO #XMLWithOpenXML (XMLData)
    SELECT CONVERT(XML, BulkColumn) AS BulkColumn 
    FROM OPENROWSET(BULK ''C:\XmlFiles\' + @FileName + ''', SINGLE_BLOB) AS x;'
    EXEC(@Query)
    SET @Index = @Index + 1
END

DECLARE @XML AS XML, @hDoc AS INT
SET @Index = 1
SELECT @Count = COUNT(*) FROM #XMLWithOpenXML 
WHILE(@Index <= @Count)
BEGIN
    SET @XML = NULL
    SELECT @XML = XMLData FROM #XMLWithOpenXML  WHERE Id = @Index
    EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

    INSERT INTO #RowDetail
    SELECT  x.colone,
            x.ColTwo,
            x.ColThree
    FROM OPENXML(@hDoc, '/root/dir/subdir')
    WITH 
    (   
        colone INT '../@Id',
        ColTwo NVARCHAR(50) '@name',
        ColThree NVARCHAR(50) '@value'
    ) AS x

    IF(@hDoc IS NOT NULL)
        EXEC sp_xml_removedocument @hDoc

    SET @Index = @Index + 1
END

我正在处理不同的 XML 格式。每种格式都包含许多 XML 文件。我必须相应地加载所有这些以及优化的方式。

【问题讨论】:

  • “这可能会影响 [影响] SQL Server 的性能” - 您为什么怀疑?
  • 我也在做 SQL 监控。当然,当通过 Openrow (SQL) 将大量 xml 文件转换为转换时,它也需要时间和资源。还有其他程序实际上做同样的事情,但存储方式不同。那就是占用SQL server的时间和资源。

标签: sql-server xml


【解决方案1】:

您如何将 XML 加载到您的 SP 中?您的评论指向OPENROW?请出示您的实际代码!

据我所知,最快的方法是将 XML 加载到类型变量中:

DECLARE @yourXML AS XML=
(
SELECT CONVERT(XML, BulkColumn,2) AS BulkColumn
FROM OPENROWSET(BULK 'PathToFile.xml', SINGLE_BLOB) AS x
);
SELECT @yourXML;

有多少个 XML,大小是多少?您可以将它们加载到一个表中,每个都在一行中。

这些 XML 是否都具有相同的结构?如果是,您可以使用 Schema 加快速度。

你如何粉碎它们(显示你的代码!)?最快的方法应该是使用 XML 方法,例如 .nodes().value().query().exist()。在非常罕见的情况下(已过时!!!)FROM OPENXML 可能值得一试...

你用 XML 做什么?读取数据并将它们填充到您的表格中?您是否更改了 XML (.modify())?你把它写回文件系统吗?

您写的是“临时表”...您在哪里以及为什么需要它们?在大多数情况下,临时表是错误思维的副作用(基于行而不是基于集合的方法)。

没有您的实际代码,很难将您指向任何地方。显示您的代码:-)

【讨论】:

  • 我对这些问题不屑一顾。这就是数据从 XML 加载并存储到临时表中的方式。此外,还有与这些临时表的连接以将值存储到表中。
  • @WaqasAhmad 好的,谢谢完整的代码,现在更清晰了...您使用的是过时的FOR OPENXML。在极少数情况下,这仍然可能是一种好方法,但不是您在此处处理此问题的方式...正如我所见,您始终采用三个值(colOne、colTwo 和 colThree)。请提供一两个示例 XML 以及您希望如何提取数据。这 - 肯定 - 更容易解决......
  • 我有不同的 XML,我必须解析每个 XML 并获取必须存储在临时表中的所需列。当我加载大量 XML 文件时,问题就出现了,然后需要时间然后第二次使用临时表,这也是一种资源消耗活动。因为我必须运行 100 多个程序。
  • @WaqasAhmad,嗯...加载 许多大 文件将需要一段时间,在所有文件上运行 XML 粉碎,所有 具有不同的结构和不同的目标表格 听起来让人头疼……当然,您使用FROM OPENXML 的方法比通过XPath/XQuery 直接从#XMLWithOpenXML 中已经存在的XML 中获取值要慢得多。我需要真实的数据示例和预期的输出来给你一个例子......
  • 嗨@WaqasAhmad 我刚刚访问了你的个人资料,发现你没有提出一票也没有接受答案。由于您是 SO 的新手(欢迎来到这里!),请给我一个提示:投票和接受是 SO 运行的燃料。请阅读:有人回答。也可以看看您的旧问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 2016-08-01
  • 2017-05-01
  • 1970-01-01
相关资源
最近更新 更多