最近做了 数据同步的 一个模块, 同步的数据,跟 缓存库中的数据 对比,看数据是进行更新 ,还是新增。
加工的时候根据标志 进行更新,或者插入。
结构: 原表 A,缓存库表 B (同原表类似,加了几个字段(标志。timestamp,同步批次等等)) ,Key_B(此表只存储了原表中的主键)
(其实现在的想法是 把要同步的数据全部原封不动的插入到缓存库,在加工的时候 在判断是新增,还是编辑。)
但是缓存库中的数据量会越来越多,比较的话,数据量非常大,而且是针对主键进行 循环 对比,数据量越来越大。
跟踪发现有部分代码跑的非常慢,其中 缓存库表 的主键(联合主键)字段的值 跟 原表 字段的值 进行一一比较,有相同的认为是
第一个想法是:看这个地方 为什么慢, 然后发现比较的地方特别耗时、
foreach (DataRow kdr in KeyData.Rows)
{
List<bool> result = new List<bool>();
foreach (DataColumn kcl in KeyData.Columns)
{
// result.Add(kdr[kcl.ColumnName].ToString().Trim() .Equals( dr[kcl.ColumnName].ToString().Trim())); //把equals 改为== 效率大概高了20倍(通过计时)
result.Add(kdr[kcl.ColumnName].ToString().Trim() == dr[kcl.ColumnName].ToString().Trim());
}
if (!result.Contains(false))//如果全部为true 则这条记录已存在 则需要编辑
{
return false;
}
}
针对 string 来说 ,虽然两者都是比较值,但是==的效率 比equals高多了。
虽然 这里改了以后,好了许多,但是 还是没有根本上改变,数据量还是那么大
第二种 想法是:加个字段吧 ,但是对于已经成熟的项目(交付阶段),再改的话涉及的比较多,不太方便。
第三种: 技术经理建议说使用临时表。
比较还是那个比较方法,只是不取数据库所有的数据进行对比 而是取 这次 原表 A 的数据,同 缓存库表 B 的数据进行 join (根据Key_B表结构 ,Key_B 的字段)取出 所有 这里 取出所有的 判断的就是 需要更新的,其他的就是需要插入的。
这里的判断 数据量就比较小了,每次取多少,比较多少。(第一次同步的时候数据量大)
(1) 建立临时表,(2)向临时表中插入 获取的原表的数据 (3) 取出join 后的需要更新的数据
这样 速度就会快很多了。
记录下来这样的一个想法。希望自己以后碰到这种情况,可以考虑到还有这样一种解决方案。