代码之家  ›  专栏  ›  技术社区  ›  Henry

大容量插入到SQL Server,插入语句对一个插入XML语句?

  •  4
  • Henry  · 技术社区  · 14 年前

    应用程序层(ColdFusion)需要在SQL Server 2005中插入多行。

    我正在考虑使用应用层中的循环来构造多个输入语句,并通过JDBC以单个连接发送到SQL Server。

    不过,我的同事建议构造一个XML,然后批量插入XML。

    哪一种方法更好?

    3 回复  |  直到 14 年前
        1
  •  4
  •   mdma    14 年前

    对于数百万行的插入,我使用了大容量插入,将数据写入SQL Server实例可以访问的csv文件。这比通过JDBC进行的任何类型的插入都要好,但是以降低灵活性为代价。对于较小的行数,使用JDBC Statement.addBatch() Statement.executeBatch() 可以用来避免发送许多小命令的开销。

    根据您的要求,您可能必须将所有这些都放在一个事务中,或者如果不需要对整个数据集提供完整的酸保证,您可能能够将这些事务拆分为多个事务。

    这是一篇讨论的文章 bulk insert of XML . 我没有可以得出任何结论的数据,但我想批量插入原始行数据会更快,因为不需要OpenXML转换。当然,如果您的数据已经是XML格式的,那么这是有意义的,但是如果不是,那么使用表格式数据可能是最简单的,也可能是最具性能的。

        2
  •  2
  •   Adrian J. Moreno    14 年前

    XML将是更好的IMO方法,尽管我还建议您创建一个存储过程来处理实际的处理,而不是运行一个内联查询。

    基本上,将XML数据作为单个参数发送,然后在sp内部运行insert into select语句,从XML中选择一些表或表组。

    DECLARE @FOO xml;
    
    SET @FOO = '<things><thing><id>1</id></thing><thing><id>2</id></thing><thing><id>3</id></thing><thing><id>4</id></thing></things>';
    
    SELECT 
        ParamValues.id.value('.', 'int') AS thing_id
    FROM 
        @FOO.nodes('/things/thing/id') AS ParamValues(id)
    

    这将创建一个具有单列“thing_id”的表。现在你要做的就是

    INSERT INTO someTable (someID)
    SELECT 
        ParamValues.id.value('.', 'int') AS thing_id
    FROM 
        @FOO.nodes('/things/thing/id') AS ParamValues(id)
    

    您可以使用一个插入来处理XML中的任意多行。

        3
  •  1
  •   duffymo    14 年前

    由于所有的网络延迟,一次插入一个插件的速度将不必要地变慢。

    一种更好的执行方式是在一次网络往返中将多个事务作为单个批处理发送,并将它们作为单个工作单元提交。

    如果您有非常多的记录,那么您可能需要考虑一种混合方法:循环处理多个批,并将它们作为工作单元提交。这将执行,即使对于大型事务也是如此,并且在提交整个事务之前,您不会强制数据库维护大型回滚日志。

    如果您的XML解决方案意味着将原始XML流作为CLOB插入,那么我不喜欢。一旦它在数据库中,您将如何查询它?您将失去SQL提供给您的一切:查询能力。如果您存储原始XML,那么您所能做的就是为特定值使用xpath。更新意味着替换整个CLOB。