如何从数据库明智地将数据块读入内存
本文关键字:数据 内存 数据库 | 更新日期: 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();
考虑使用Skip
和Take
进行这种分块方式。阅读这里和这里的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();
等。