执行查询时
Mymodel.all.each do |model|
# ..do something
end
它使用了大量的内存和已用内存的数量一直在增加并且崩溃了。我发现要修复它我需要禁用identity_map但是当我添加到mongoid.yml
文件identity_map_enabled: false
时我收到错误
Invalid configuration option: identity_map_enabled.
Summary:
A invalid configuration option was provided in your mongoid.yml, or a typo is potentially present. The valid configuration options are: :include_root_in_json, :include_type_for_serialization, :preload_models, :raise_not_found_error, :scope_overwrite_exception, :duplicate_fields_exception, :use_activesupport_time_zone, :use_utc.
Resolution:
Remove the invalid option or fix the typo. If you were expecting the option to be there, please consult the following page with repect to Mongoid's configuration:
I am using Rails 4 and Mongoid 4, Mymodel.all.count => 3202400
如何修复它或者某些人知道减少执行查询期间使用的内存量的其他方法.all.each ..? 非常感谢你的帮助!!!!
答案 0 :(得分:1)
我开始使用与你一样的东西,通过数百万条记录进行循环,内存不断增加。
原始代码:
@portal.listings.each do |listing|
listing.do_something
end
我已经通过了许多论坛答案,我试了一下。
第一次尝试:我尝试使用WeakRef
和GC.start
的组合,但没有运气,我失败了。
第二次尝试:在第一次尝试时添加listing = nil
,但仍然失败。
成功尝试:
@start_date = 10.years.ago
@end_date = 1.day.ago
while @start_date < @end_date
@portal.listings.where(created_at: @start_date..@start_date.next_month).each do |listing|
listing.do_something
end
@start_date = @start_date.next_month
end
<强>结论强>
在此期间永远不会释放为记录分配的所有内存 查询请求。因此,每次尝试少量记录 请求完成工作,内存状况良好,因为它会 在每次请求后发布。
答案 1 :(得分:0)
您的问题不是身份地图,我不认为Mongoid4甚至内置了身份地图,因此当您尝试将其关闭时会出现配置错误。您的问题是您正在使用all
。当你这样做时:
Mymodel.all.each
Mongoid将尝试在db.mymodels
集合中将每个单个文档实例化为Mymodel
实例,然后再开始迭代。你说集合中有大约320万个文档,这意味着Mongoid将尝试在尝试迭代之前创建320万个模型实例。大概你没有足够的内存来处理那么多对象。
您的Mymodel.all.count
工作正常,因为它只是向数据库发送一个简单的count
调用并返回一个数字,它根本不会实例化任何模型。
解决方案是不使用all
(并且最好忘记它存在)。根据“做某事”的作用,您可以:
mapReduce
或聚合框架将逻辑推入数据库。每当您使用真实数据(即除了一个非常小的数据库之外的其他东西)时,您应该尽可能多地将数据推送到数据库中,因为数据库是为了管理和操作大量数据而构建的。