【问题标题】:Fast and simple way to import csv to SQL Server将 csv 导入 SQL Server 的快速简单方法
【发布时间】:2016-04-12 14:21:57
【问题描述】:

我们使用CSVReader 导入一个csv 文件,然后使用SqlBulkCopy 将该数据插入SQL Server。这段代码适用于我们并且非常简单,但想知道是否有更快的方法(我们的一些文件有 100000 行)也不会变得太复杂?

        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
        SqlTransaction transaction = conn.BeginTransaction();
        try
        {
            using (TextReader reader = File.OpenText(sourceFileLocation))
            {
                CsvReader csv = new CsvReader(reader, true);
                SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, transaction);
                copy.DestinationTableName = reportType.ToString();
                copy.WriteToServer(csv);
                transaction.Commit();
            }
        }
        catch (Exception ex)
        {
            transaction.Rollback();
            success = false;
            SendFileImportErrorEmail(Path.GetFileName(sourceFileLocation), ex.Message);
        }
        finally
        {
            conn.Close();
        }

【问题讨论】:

  • 我怀疑你会找到比这更快的东西。现在需要多长时间?您预计需要多长时间?
  • 4 分钟,将包含 180,000 行的 csv 文件作为我们的测试数据。与我们宁愿不使用 SSIS 的 1.5 分钟相比。
  • 如果性能在您的集成方案中至关重要,我会推荐 SSIS,即使它有其缺陷...在 SQL Server 2012+ 上,您还可以通过 Visual Studio 开发 SSDT。
  • CSV 文件中有多少个字段? 180k 行的文件有多大? 4 分钟对于只有 180k 行来说似乎异常长,尤其是对于通过SqlBulkCopy 进行直接插入的情况。此外,您的示例代码中可能存在复制/粘贴错误,因为它看到整个代码块被复制,而不是第一个 finally 块中的关闭 }
  • 你到底在使用什么“CsvReader”代码?我发现了一些不同的,但我猜你正在使用它返回一个DataTable。如果是这样,那么在调用 SqlBulkCopy 之前将整个 CSV 加载到内存中可以解释它所花费的 4 分钟,以及为什么 SSIS 没有花费这么长时间。与 SSIS 类似,我在answer 中描述的方法也将数据从文件流式传输到 SQL Server,因此它不会首先完全加载到内存中:-)。

标签: c# .net sql-server sqlbulkcopy


【解决方案1】:

您应该考虑使用基于用户定义表类型 (UDTT) 的表值参数 (TVP)。此功能是在 SQL Server 2008 中引入的,允许您定义可用于将数据流式传输到 SQL Server 的强类型结构(如果操作正确)。与使用SqlBulkCopy 相比,这种方法的一个优点是您可以在表格中做的不仅仅是简单的INSERT;你可以做任何你想做的逻辑(验证/更新/等),因为数据以表变量的形式到达。如果需要先暂存任何数据,您可以在单个存储过程中处理所有导入逻辑,该存储过程可以轻松使用本地临时表。这使得隔离进程变得相当容易,这样您就可以同时运行多个实例,只要您有办法在逻辑上分离正在导入的行。

我在 S.O. 上发布了有关此主题的详细答案。不久前,包括示例代码和其他信息的链接:

How can I insert 10 million records in the shortest time possible?

甚至还有一个指向我的相关答案的链接,其中显示了该主题的另一个变体。我在某处有第三个答案,如果您有数百万行,则显示批处理方法,但您没有,但是一旦我发现我会在此处添加链接。

【讨论】:

    【解决方案2】:

    不要构建自己的工具来执行此操作,而是查看SQL Server Import and Export / SSIS。您可以直接以平面文件和 SQL Server 数据库为目标。输出dtsx 包也可以从命令行运行或通过 SQL Server 代理作为作业运行。

    我之所以建议这样做是因为该向导针对并行性进行了优化,并且在大型平面文件上运行得非常好。

    【讨论】:

    • 谢谢。这会作为一个自动化过程工作吗?
    • 是的,例如,您可以将 SQL Server 中的包安排为作业/任务。我通常从向导开始,然后根据您的 SQL Server 版本修改 BIDS/SSDT 中的包(请参阅我对您原始问题的评论)。
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2012-03-12
    • 2010-09-23
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多