<div dir="ltr"><div>For a bit of background, the use of the "includes" is all to do with the N+1 problem - read this for more info: <a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations" target="_blank">http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations</a><br></div><div><br></div><div>I don't think the order of the "includes" or "where" will make a difference though.</div><div><br></div><div>Fred's suggestion of loading into separate hashes may work, but to be honest it sounds like you're going to need to look at rewriting this stuff anyway. Presumably either the FeedBuilder or ResponseBuilder is going to call into the FeedDetail's associations which will make that difficult. Without seeing those classes I'm not sure what else to suggest other than a potential rewrite...</div><div><br></div><div>Alternatively, if you're getting that much data in a single request it might be worth investing time in paginating the results, instead of a complete rewrite, as Julius has just suggested whilst I type this :)</div><div><br></div><div>Cheers,</div><div><br>Ed</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 14 December 2015 at 13:50, Frederick Cheung <span dir="ltr"><<a href="mailto:frederick.cheung@gmail.com" target="_blank">frederick.cheung@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><div style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto"><br></div> <br> <div></div> <br><p>On 14 December 2015 at 12:47:21, Marco Iannone (<a href="mailto:marco.iannone@gmail.com" target="_blank">marco.iannone@gmail.com</a>) wrote:</p> <blockquote type="cite"><span><div><div></div><div>
<div dir="ltr">
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
Hello,<br>
<br>
</div>
Ruby newbie question alert
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
: many apologies if it's too basic, or not the type of questions
for this forum.<br>
At least I can say we tried hard before going to <a href="http://stackoverflow.com/questions/34227034/manipulating-activerecord-objects-to-build-json" target="_blank">
StackOverflow</a></div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
, and now here.</div>
<br>
<br>
We're trying to
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
ensure a webpage loads faster. The main issue</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
relates to a few activerecord-generated queries on that
page.<br></div>
<br>
If you look at the SQL they generate, the queries are as follows
(all code a bit simplified):<br>
<br>
select * from feed_details where account_id = 5<br>
select * from feeds where id in
(VERY_LONG_LIST_OF_IDS_FROM_FIRST_QUERY)<br>
select * from feeds_metadata where feed_id in
(VERY_LONG_LIST_FROM_FIRST_QUERY)<br>
select * from documents where feed_id in
(VERY_LONG_LIST_FROM_FIRST_QUERY)<br>
<br>
All the indexes are in place, but we verified that they'd take less
than half the time by changing
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
each of them to:<br></div>
<br>
select * from feeds, feed_details where id = feed_id and account_id
= 5<br>
select * from feeds_metadata fm, feed_details fd where fm.feed_id =
fd.feed_id and account_id = 5<br>
select * from documents where d, feed_details fd where d.feed_id =
fd.feed_id and account_id = 5<br>
<br></div></div></div></span></blockquote><div><br></div><div><br></div></span>That in a nutshell is the difference between .preloads and .eager_load (.includes defaults to preloads), except that .eager_load runs one query<div>to load all the associations. This can perform badly when there are multiple has_many being loaded (as in your case) , since you end up pretty much with the cartesian product. Worth a try though.</div><span class=""><div><br></div><div><blockquote type="cite"><span><div><div><div dir="ltr">This generates an active record object with the data from the
above-mentioned queries, that is used in the controller to build
the JSON that is sent to the webpage as in below (see feeds_data
line):<br>
<br>
def index<br>
consumer =
ConsumerWithAccount.new(current_user.account)<br>
feed_builder = FeedBuilder<br>
feeds_data =
FeedDetail.feeds_data_for_account(<a href="http://current_user.account.id" target="_blank">current_user.account.id</a>)<br>
<br>
render json: ResponseBuilder.new(consumer,
feed_builder, feeds_data)<br>
end<br>
<br>
To use the faster queries, we were hoping to build the feeds_data
activerecord object
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
by using the faster queries; this gets passed to the JSON
builder. That would</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
seem to require getting rid of the "involves", which (seemingly)
uses the IN ().<br></div>
<br>
If useful, we have the
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
more effective activerecord for the 3 queries, they look
like:<br></div>
Feed.joins(:feed_details).where(feed_document_sets: {account_id:
current_account_id})<br>
<br>
But we couldn't figure out how to build that
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
</div>
activerecord object
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
, or one that can be parsed in a similar way by the
responsebuilder</div>
: therein lies the proverbial rub.
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
<br>
Intense googling and referring to rails docs hasn't helped.</div>
<br>
<br></div></div></div></span></blockquote><div><br></div><div><br></div></div></span><div>Sometimes you can crowbar this sort of stuff in: load the objects for each of the tables in whatever way is the fastest, keep them in a hash so that you can easily identify which ones belongs to which feed detail. Then fiddle with some_feed_detail.association(:association_name).target to side load in the data. This may not work if response builder expects to have an active record relation rather than an array (i.e. it wants to chain more stuff onto the scope)</div><div><br></div><div>Fred</div><div><br></div></div><br>_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>
Archives: <a href="http://lists.lrug.org/pipermail/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/pipermail/chat-lrug.org</a><br>
Manage your subscription: <a href="http://lists.lrug.org/options.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/options.cgi/chat-lrug.org</a><br>
List info: <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
<br></blockquote></div><br></div>