如何从数据库明智地将数据块读入内存

本文关键字:数据 内存 数据库 | 更新日期: 2023-09-27 18:15:50

基本上我想要完成的是在数据库中执行大量数据的CRUD操作(使用mvc 4, LINQ)这里有一个叫留言的表。我需要查询它并检索那些具有folderid = 10(其数量超过一百万)的MSGS

<List>Messages msgList = from msg in db.messages
                         where msg.folderid.equals(10)
                         select msg).tolist();

这将在msgList集合中返回一百万。我希望以块的形式检索记录,比如一次大约5000条。请帮助!

如何从数据库明智地将数据块读入内存

目前的另外两个答案(Kuruvilla &本)两者都有你可能需要考虑的注意事项……

1)使用一个标志意味着你需要更新这个数据库来跟踪处理的消息。这可能可行,也可能不可行。但这不是唯一的方法

2)如果您确定调用之间没有添加项,则使用skip和take是一个好主意。这被称为分页,如果发生这种情况,它可能意味着第二页包含您已经处理过的项!

如果你担心这两点中的任何一点,那么我建议你按Id排序你的消息,跟踪最后处理的Id,并在where子句中使用它,与Take:

var msgList = (from msg in db.messages
               order by msg.id
               where msg.id > lastProcessedId
               select msg).Take(5000).ToList();

在处理完每条消息后持久化lastProcessedId,这样如果出现任何问题,您可以继续您离开的地方

您最好在完成第一个5000之后设置Flag,并更新每个记录的标志。现在你可以再拿5000个没有以上标志的。

var msgList = (from msg in db.messages
                         where msg.folderid ==10 && msg.flag
                              select msg).Take(5000).ToList();

考虑使用SkipTake进行这种分块方式。阅读这里和这里的skip和take。在您的情况下,您可能想要包装您的查询(在查询语法中),以便调用这些方法(它们仅在流畅语法中可用)。确保在调用ToList之前使用Take,此时将记录调用到内存中。对于前100条记录,使用:

var msgList = (from msg in db.messages
               where msg.folderid == 10
               select msg).Take(100).ToList();

然后对于接下来的100条记录使用:

var msgList = (from msg in db.messages
               where msg.folderid == 10
               select msg).Skip(100).Take(100).ToList();

等。