如何对比两个DataTable并使用多线程更新第一个表的记录
优化方案
首先你现有代码的性能瓶颈不止是没有用多线程,核心问题是嵌套循环的时间复杂度为O(n*m),如果表2同样是10万级数据,比对次数会达到百亿级,这才是运行慢的核心原因。优化分两步走:
第一步:先优化匹配逻辑,把查找复杂度降到O(1)
先把表2的所有Id预存到HashSet<string>中,避免每次都遍历表2:
DataTable dt = getRecordsfromTable1(); DataTable dt1 = getRecordsfromTable2(); // 预存表2的所有Id,仅需遍历表2一次 HashSet<string> dt2IdSet = new HashSet<string>(); foreach(DataRow dr1 in dt1.Rows) { string id = dr1["Id"].ToString(); if(!dt2IdSet.Contains(id)) dt2IdSet.Add(id); }
第二步:用多线程并行处理表1的记录
用.NET内置的Parallel.ForEach并行遍历表1的行,充分利用CPU多核性能,同时注意规避线程安全问题:
// 配置并行度,可根据你的CPU核心数、数据库承载能力调整,避免压垮数据库 ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 2 }; Parallel.ForEach(dt.AsEnumerable(), parallelOptions, dr => { string currentId = dr["Id"].ToString(); if(dt2IdSet.Contains(currentId)) { // 匹配成功调用更新方法 Update(currentId); } else { // 匹配失败赋值Notes,不同线程操作不同行,DataTable行级写是线程安全的 dr["Notes"] = "未找到匹配记录"; } });
额外优化建议
- 如果
Update方法是单条操作数据库,建议把需要更新的Id先批量收集,最后做批量更新,避免频繁的数据库IO请求,性能会提升10倍以上 - 如果表2的Id有重复,可改用
Dictionary<string, DataRow>存储表2的数据,方便匹配时直接取表2的字段值更新表1,无需二次查找 - 若
Update方法涉及共享资源访问,需要加锁避免并发冲突
内容的提问来源于stack exchange,提问作者aniket narvankar
相关产品推荐
相关产品推荐

