如何比较两个数据表并使用多个线程更新第一个数据表?

Posted

技术标签:

【中文标题】如何比较两个数据表并使用多个线程更新第一个数据表?【英文标题】:How to compare two DataTables and update the first DataTable using multiple threads? 【发布时间】:2021-11-20 05:32:58 【问题描述】:

表1中有150,000条记录,我必须将表1中的每条记录与表2中的相应记录一一比较,如果找到匹配更新表1中的相同记录,如果找不到匹配需要更新Notes 表 1 中的列值未找到匹配记录。

为此,我分别从dtdt1 的两个表中获取记录。

下面是我做的代码

DataTable dt = getRecordsfromTable1();
DataTable dt1 = getRecordsfromTable2();
foreach(DataRow dr in dt.Rows)

     foreach(DataRow dr1 in dt1.Rows)
     
          if(dr["Id"].ToString() == dr1["Id"].ToString())
          
               //Calling update method in Data Access Layer to Update record in First table
               Update(dr["Id"].ToString());
          
          else
         
             //Id not found
         
     

但这工作非常缓慢,因为我正在逐一比较 150,000 条记录。如何在这里使用多线程概念来加快处理速度?

【问题讨论】:

更好地使用针对这种事情特别优化的方法。您的代码效率极低且复杂度为 O(n^2) - 再多的多线程也不会显着加快速度。改为查看Enumerable.Join()(另外:您在ID 上对ToString() 的调用似乎是多余的,很可能) 多线程对于 CPU 密集型计算很有用。这对 IO 不利。 这个任务最好通过 MERGE SQL 语句来完成。 比较 150,000 条记录不应该在 C# 中完成,因为它不是为这种类型的工作负载设计的。另一方面,数据库是明确的。为正确的工作使用正确的工具。 150000 这不是很多记录。数据库已经可以比任何客户端快得多完成您要求的操作,因为它可以使用索引并且比任何客户端都拥有更快的 CPU、RAM 和磁盘。以数量级更快(1000、10K、100K) 【参考方案1】:

在这里尝试的第一件事是在Id 上建立索引,即

Dictionary<string, DataRow> lookup = new();
// index dt1
foreach(DataRow dr1 in dt1.Rows)

    var id = dr1["Id"].ToString();
    lookup.Add(id, dr1);

// now enumerate dt
foreach(DataRow dr in dt.Rows)

    var id = dr["Id"].ToString();
    if (lookup.TryGetValue(id, out var dr1))
    
        //Calling update method in Data Access Layer to Update record in First table
        Update(id);
    

注意:如果Update 实际上不需要dr1,您也可以将Dictionary&lt;string, DataRow&gt; 替换为已知ID 的HashSet&lt;string&gt;

至于并行化:这在很大程度上取决于 Update 所做的事情;并行化可能有用也可能没用。很高兴讨论更多,但是:需要看到它。如果它可以简单地并行化,那么可能简单地使用就足够了:

// now enumerate dt concurrently
Parallel.ForEach(dt.AsEnumerable(), dr =>

    var id = dr["Id"].ToString();
    if (lookup.TryGetValue(id, out var dr1))
    
        //Calling update method in Data Access Layer to Update record in First table
        Update(id);
    
);

但是,与数据库相关的代码必须是可并行化的。

【讨论】:

Parallel.ForEach 不工作给出错误。 System.AggregateException,连接未关闭,连接当前状态为正在连接 我尝试了foreach,但完成过程花了4个小时

以上是关于如何比较两个数据表并使用多个线程更新第一个数据表?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建从多个数据更新的Flowable?

Access - 比较两个表并在第一个表中更新或插入数据

如何在两个数据流PYTHON中连接图表和在线图表的报价?

Android 异步更新UI-线程池-Future-Handler实例分析

比较两个数据框并更新值

如何创建CRUD方法的多个重载? [关闭]