最快将csv导入数据库表

我已经实现了一个导入function,它从Asp.Net应用程序中的csv文件中获取数据。 大小的文件可以从几kb到最大10 MB不等。

但是,当导入发生时,如果文件大小> 50000,则大约需要20分钟。 这太过分了。 我需要在2-3分钟的时间内执行大约300000条记录的导入。

我知道导入到数据库还取决于数据库服务器的物理内存。我将批量创建插入脚本并执行。 我也知道使用SqlBulkCopy也是另一种选择,但在我的情况下,它不是插入产品的发生,而是更新和删除这是一个名为“FUNCTION CODE”的字段,决定是否插入,更新或删除。

关于如何解决这个问题的任何建议将不胜感激。

实现这一目标的一种方法是实现同时执行进程的多个线程,但我从未实现过直到日期的线程,因此我不知道通过实现相同的复杂性。

感谢和问候,弗朗西斯P.

SqlBulkCopy绝对是最快的。 我会通过将数据插入数据库的临时表来实现此目的。 一旦数据在临时表中,您就可以使用SQL来相应地合并/插入/删除。

我猜你正在使用SQL Server …

如果您使用的是2005/2008,请考虑使用SSIS来处理该文件。 的Technet

在asp.net进程中导入大量数据并不是你能做的最好的事情。 您可以上传文件并启动一个为您带来魔力的过程。

如果这是一个重复的过程并且文件是通过asp.net上传的,那么你正在做一些关于数据的决策来决定插入/更新或删除,然后试试http://www.codeproject.com/KB/database/ CsvReader.aspx是这个快速的csv阅读器。 它具有记忆速度快,经济实惠

您正在按顺序执行1个连接的所有数据库查询。 因此,对于每次插入/更新/删除,您都要通过线路发送命令,等待数据库执行此操作,然后在发送回事件时再次唤醒。

数据库针对大量并行访问进行了优化。 因此,有两条简单的路线可以实现显着的加速:

打开与数据库的X连接(你必须调整X但只是从5开始)并且要么:启动5个线程,每个线程执行你正在做的相同工作的一部分。 或:使用异步调用 ,当回调到达时,请在下一个查询中进行搜索。

我建议使用SQL Server 2005/2008中的XMLfunction,它允许您批量插入和批量更新。 我采取以下方法:

  • 将整个文件处理为内存数据结构。
  • 从此结构创建单个XML文档以传递到存储过程。
  • 创建存储过程以将XML文档中的数据加载到临时表中,然后执行插入和更新。 有关创建存储过程的指导,请参见下文。

这种方法有很多优点:

  • 整个操作在一次数据库调用中完成,但如果您的数据集非常大,则可能需要对其进行批处理。
  • 您可以轻松地将所有数据库写入包装到单个事务中,并在任何失败时回滚。
  • 您没有使用任何动态SQL,这可能会带来安全风险。
  • 您可以使用OUTPUT子句返回插入,更新和/或删除的记录的ID。

就您将需要的存储过程而言,类似下面的内容应该有效:

CREATE PROCEDURE MyBulkUpdater ( @p_XmlData VARCHAR(MAX) ) AS DECLARE @hDoc INT EXEC sp_xml_preparedocument @hDoc OUTPUT, @p_XmlData -- Temporary table, should contain the same schema as the table you want to update CREATE TABLE #MyTempTable ( -- ... ) INSERT INTO #MyTempTable ( [Field1], [Field2] ) SELECT XMLData.Field1, XMLData.Field2 FROM OPENXML (@hdoc, 'ROOT/MyRealTable', 1) WITH ( [Field1] int, [Field2] varchar(50), [__ORDERBY] int ) AS XMLData EXEC sp_xml_removedocument @hDoc 

现在,您可以根据需要从临时表中简单地插入,更新和删除您的真实表格,例如

 INSERT INTO MyRealTable (Field1, Field2) SELECT Field1, Field2 FROM #MyTempTable WHERE ... UPDATE MyRealTable SET rt.Field2 = tt.Field2 FROM MyRealTable rt JOIN MyTempTable tt ON tt.Field1 = MyRealTable.Field1 WHERE ... 

有关您需要传入的XML的示例,您可以执行以下操作:

 SELECT TOP 1 *, 0 AS __ORDERBY FROM MyRealTable AS MyRealTable FOR XML AUTO, ROOT('ROOT') 

有关更多信息,请参阅OPENXML , sp_xml_preparedocument和sp_xml_removedocument 。