【问题标题】:How to insert/Update 10000 rows in SQL Server using C# efficiently while comparing each row from database如何在比较数据库中的每一行时有效地使用 C# 在 SQL Server 中插入/更新 10000 行
【发布时间】:2020-03-12 23:01:06
【问题描述】:

客户给了我一个 Excel 文件。它有 4 列:ID、名称、地点、日期)。

我的数据库中有一个存储这些值的表。我必须检查 Excel 中的每一行并将其值与数据库表进行比较。如果行已存在,则比较日期并从 Excel 更新为最新日期。如果该行尚不存在,则插入一个新行。

我正在获取每一行并使用 for 循环比较其值,并通过创建数据表适配器使用插入/更新语句更新数据库。

我的问题是此操作需要 4 多个小时才能更新数据。有没有有效的方法来做到这一点?我搜索了很多,找到了SqlBulkCopy 之类的选项,但是我将如何比较数据库中的每一行?

我正在使用带有 C# 和 SQL Server 的 ASP.NET。

这是我的代码:

for (var row = 2; row <= workSheet.Dimension.End.Row; row++)
{
    // Get data from excel 
    var Id = workSheet.Cells[row, 1].Text;
    var Name = workSheet.Cells[row, 2].Text;
    var Place = workSheet.Cells[row, 3].Text;
    var dateInExcel = workSheet.Cells[row, 4].Text;

    // check in database if ID exists in database then compare date and update database> 
    if (ID.Rows.Count <= 0) //no row exist in database 
    {
        // Insert row in the database using data table adapter's insert statement 
    }
    else if (Id.Rows.Count > 0) //Id exists in database 
    {  
        if (Db.DateInDB < (dateUpdate)) // compare dates 
        {
            // Update database with the new date using data table adapter Update statement.
        }
    }
}

【问题讨论】:

  • SqlBulkCopy 到临时表中。合并到目标表中。
  • 目标表中有多少条记录?
  • 与@mjwills 提到的一种类似的技术是将 Excel 数据加载到 DataTable 并作为表值参数传递以在 T-SQL MERGE 语句中使用。见this example
  • @DanGuzman 好电话。有点慢,但通常更容易编写。
  • @tymtam:目标表没有记录。我每个月都会收到这个文件,所以第一次插入后记录会大大增加。

标签: c# asp.net sql-server excel


【解决方案1】:

@mjwills 和@Dan Guzman 在 cmets 部分提出了非常有效的观点。

我的建议是创建一个 SSIS 包以将电子表格导入临时表,然后使用合并查询/查询对所需表进行条件更新。

https://docs.microsoft.com/en-us/sql/integration-services/import-export-data/start-the-sql-server-import-and-export-wizard?view=sql-server-ver15

获得良好起点的最简单方法是使用 SSMS 中的导入向导并保存生成的包。在 Visual Studio 中创建一个 SSIS 项目(对于目标 SQL Server 版本,您需要安装正确版本的 BI)

https://docs.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt?view=sql-server-ver15

https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15

这种方法将利用 SQL 做它最擅长的事情,处理关系数据集,并将其移出 asp 代码。

要调用它,ASP 应用程序需要处理初始文件上传/无论什么,然后调用 SSIS 包。

这可以通过将 SSIS 包设置为 SQL Server 上的作业来完成,没有计划,然后在您希望它运行时启动该作业。

How to execute an SSIS package from .NET?

很可能可以对这种方法进行一些优化;但它应该在原则上起作用。

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    10_000 条记录超过 3x3600s 表明每条记录 >1s - 我认为应该可以改进这一点。

    在数据库中完成这项工作会获得最佳性能,但您可以先做的事情很少。

    1. 检查基础知识:

      • 索引
      • 网络速度。您的时间是否基于尝试使用您的计算机并与云数据库通信?如果代码和数据库在同一个云(Azure/Amazon/etc.)中,它可能比您在办公室计算机上运行的代码与远处的数据库交谈时所测量的要快得多。
    2. 使用批处理。如果您分批工作而不是一次一个记录,您应该能够获得更好的性能。

      • 从 CSV 中获取 10、100、500 或 1000 条记录,并从 db 中获取相应的记录。检查内存中的存在和日期比较。之后执行一次保存到数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2014-12-15
      • 1970-01-01
      相关资源
      最近更新 更多