字典/列表数据库更新速度

时间:2011-08-19 15:31:39

标签: c# linq-to-sql

我的模型根据一些字典形式的信息更新了数据库。我目前的做法如下:

SortedItems = db.SortedItems.ToList();
foreach (SortedItem si in SortedItems)
{
    string key = si.PK1 + si.PK2 + si.PK3 + si.PK4;
    if (updates.ContainsKey(key) && updatas[key] != si.SortRank)
    {
        si.SortRank = updates[key];
        db.SortedItems.ApplyCurrentValues(si);
    }
}
db.SaveChanges();

迭代字典会更快,并为每个项目执行数据库查找吗?字典仅包含已更改的项目,可以是从2个项目到整个集合的任意位置。我对替代方法的想法是:

foreach(KeyValuePair<string, int?> kvp in updates)
{
    SortedItem si = db.SortedItems.Single(s => (s.PK1 + s.PK2 + s.PK3 + s.PK4).Equals(kvp.Key));
    si.SortRank = kvp.Value;
    db.SortedItems.ApplyCurrentValues(si);
}
db.SaveChanges();

编辑:假设更新次数通常约为db entires的5-20%

2 个答案:

答案 0 :(得分:4)

让我们看看:

方法1:

  • 您将遍历数据库中的所有1000个项目
  • 你仍然会访问字典中的每一项,并且对字典有950次未命中
  • 您仍然需要对数据库进行50次更新调用。

方法2:

  • 你会迭代字典中的每个项目而字典中没有遗漏
  • 您将对数据库进行50次单独查找调用。
  • 您需要对数据库进行50次更新调用。

这实际上取决于数据集的大小以及平均值被修改的百分比。

您也可以这样做:

方法3:

  • 从词典中构建一组所有键
  • 查询数据库一次以查找与这些键匹配的所有项目
  • 迭代结果并更新每个项目

就个人而言,我会尝试确定您的典型案例场景,并对每个解决方案进行分析,以确定哪个最佳。我真的认为第二个解决方案会导致大量的数据库和网络命中,如果你有一个大的集合和大量的更新,因为每次更新它必须打两次数据库(一次得到项目,一次更新项目。)

所以是的,这是一个非常长篇大论的说法,“这取决于......”

如果有疑问,我会根据生产场景的复制品对两者进行编码和计时。

答案 1 :(得分:0)

要添加@James的答案,您可以使用存储过程(或常规SQL命令)获得最快的结果。

LINQ-to-Entities(以及其他LINQ提供程序,如果它们最近没有更新)的问题是它们不知道如何使用where子句生成SQL更新:

update SortedItems set SortRank = @NewRank where PK1 = @PK1 and (etc.)

存储过程将在服务器端执行此操作,您只需要一次数据库调用。