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

发布于 2024-11-30 23:36:06 字数 792 浏览 0 评论 0原文

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

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();

编辑:假设更新数量通常约为数据库总数的 5-20%

I've got my model updating the database according to some information that comes in in the form of a Dictionary. The way I currently do it is below:

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();

Would it be faster to iterate through the dictionary, and do a db lookup for each item? The dictionary only contains the item that have changed, and can be anywhere from 2 items to the entire set. My idea for the alternate method would be:

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();

EDIT: Assume the number of updates is usually about 5-20% of the db entires

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缺⑴份安定 2024-12-07 23:36:06

让我们看一下:

方法 1:

  • 您将迭代数据库中的所有 1000 个项目
  • 您仍然会访问词典中的每个项目,并且对词典有 950 次未命中
  • 您仍然有 50 次更新调用数据库。

方法 2:

  • 您将迭代字典中的每个项目,并且不会遗漏字典中的内容。
  • 您将对数据库进行 50 次单独的查找调用。
  • 您将对数据库进行 50 次更新调用。

这实际上取决于数据集有多大以及平均修改的百分比是多少。

您还可以执行以下操作:

方法 3:

  • 构建字典中所有键的集合
  • 针对与这些键匹配的所有项目查询数据库一次
  • 迭代结果并更新每个项目

就我个人而言,我会尝试确定您的典型案例场景并分析每个解决方案,看看哪个是最好的。不过,我真的认为第二个解决方案将导致大量的数据库和网络点击,如果你有一个大的集合和大量的更新,因为对于每个更新,它必须点击数据库两次(一次以获得项目,一次更新项目)。

所以,是的,这是一种非常冗长的说法,“这取决于……”

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

Let's look:

Method 1:

  • You'd iterate through all 1000 items in the database
  • You'd still visit every item in the Dictionary and have 950 misses against the dictionary
  • You'd still have 50 update calls to the database.

Method 2:

  • You'd iterate every item in the dictionary with no misses in the dictionary
  • You'd have 50 individual lookup calls to the database.
  • You'd have 50 update calls to the database.

This really depends on how big the dataset is and what % on average get modified.

You could also do something like this:

Method 3:

  • Build a set of all the keys from the dictionary
  • Query the database once for all items matching those keys
  • Iterate over the results and update each item

Personally, I would try to determine your typical case scenario and profile each solution to see which is best. I really think the 2nd solution, though, will result in a ton of database and network hits if you have a large set and a large number of updates, since for each update it would have to hit the database twice (once to get the item, once to update the item).

So yes, this is a very long winded way of saying, "it depends..."

When in doubt, I'd code both and time them based on reproductions of production scenarios.

〃温暖了心ぐ 2024-12-07 23:36:06

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

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

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

存储过程就可以了这是在服务器端,您只需要一个数据库调用。

To add to @James' answer, you would get fastest results using a stored proc (or a regular SQL command).

The problem with LINQ-to-Entities (and other LINQ providers, if they haven't updated recently) is that they don't know how to produce SQL updates with where clauses:

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

A stored procedure would do this at the server side, and you would only need a single db call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文