在PHP(过去)中,您使用mysql_fetch_assoc
逐行打印html上的内容。
基本上,tou正在对某些sql结果进行循环,而不将整个结果存储在内存中。
我有一种情况,当我正在进行一个非常大的查询时,它“加入”所有必需的表来形成一个大行,所以当我请求例如一个关联的模型时,查询不会调用数据库,因为数据被视为“缓存”。
这个查询的最大问题是,它是巨大的,它将很多东西加载到内存中。 因为是使用连接构建的,所以我真的不需要在内存中一次加载所有使用过的表的所有数据,因为每一行都可以直接打印(感谢这个连接),所以我的想法基本上是在每个获取的行上创建一个循环并直接打印,然后丢弃。
我怎样才能实现这样的目标?
这是我正在使用的粗略表结构(未完成):
Trips
- has_many Hikers
- belongs_to Organization
Hikers
- belongs_to PersonalRecord
PersonalRecord
Organization
- has_many Trips
我的加入只需要进行所有旅行,并将此表的每一行加入组织,徒步旅行者和个人记录。
更新1:
目前我正在使用此查询来获取结果:
table_join_to_cache = '
INNER JOIN organizations ON organizations.id = trips.organization_id
LEFT JOIN cities ON cities.id = trips.city_id
LEFT JOIN hiker_trips ON hiker_trips.trip_id = trips.id
LEFT JOIN hikers ON hikers.id = hiker_trips.hiker_id
LEFT JOIN personal_records ON personal_records.id = hikers.personal_record_id
LEFT JOIN trip_trip_levels ON trip_trip_levels.trip_id = trips.id
LEFT JOIN trip_levels ON trip_levels.id = trip_trip_levels.trip_level_id
'
@trips = Trip.joins(table_join_to_cache)
.where('trips.begin_date >= ? AND trips.begin_date <= ?', begin_of_month, end_of_month)
.uniq.order('begin_date ASC, title ASC')
如果我需要例如特定组织的旅行,我可以选择添加其他条件。
N.B。如果可能,我想避免分页。
我的想法:在我的想象中,这应该像“光标”一样,我进行查询,而不是像@trips_cursor = myquery
那样存储,然后在视图trips_cursor.each_row do |trip|
中每次循环时都需要创建一个模型对象(并丢弃它)。它可以是非常简单的。
我需要ruby on rails代码,而不是PHP
更新回答
由于我已经学到了一些东西,我想分享一些我发现的信息。
首先,如果你使用AR查询(where,join,limit和一些类似的方法),查询将不会运行(延迟加载),直到你在查询上运行一个方法,这不是一个 AR方法。基本上每个each
方法都会触发查询。如果您执行find_each(batch_size: 1)
,在未被触发的AR查询上,它将只在内存中加载一行并每次打印出来,保留您宝贵的RAM。请注意,我使用这种方法只是因为,由于我的巨大连接,我加载了所需的一切,所有记录都是唯一的,所以我不要求它们被缓存。
答案 0 :(得分:1)
检查此链接:
http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects-in-batches
我认为你所要求的是find_each
方法。默认情况下,一次加载1000行可能没问题,但您可以将其配置为获取更少或更多。
我希望有所帮助。
答案 1 :(得分:1)
使用find_each或find_in_batches的示例(可能更好)如果@trips是视图中的关系:
<%= @trips.find_in_batches do |trips| %>
<%= render partial: trips %>
<% end %>
那是怎么回事?
另外,如果结果非常大,我强烈建议您考虑使用某种形式的缓存,如ActiveSupport :: Cache :: Store:http://guides.rubyonrails.org/caching_with_rails.html#activesupport-cache-store
答案 2 :(得分:0)
我确信有很多聪明的解决方案,但为什么不在SQL查询中使用好的旧LIMIT?只需获取500行即可处理它们并获取更多信息。