New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A bug? Query the whole table when using find_in_batches and find_each #25537
Comments
Please provide a script that we can use to reproduce the issue using our standard bug report template |
Ok. I have provided a script in the description above. |
I think this only happens when def inspect
entries = records.take([limit_value, 11].compact.min).map!(&:inspect)
entries[10] = '...' if entries.size == 11
"#<#{self.class.name} [#{entries.join(', ')}]>"
end Maybe it's better if Something like this: diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index d042fe5..177ceba 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -680,7 +680,9 @@ def values
end
def inspect
- entries = records.take([limit_value, 11].compact.min).map!(&:inspect)
+ subject = loaded? ? records : self
+ entries = subject.take([limit_value, 11].compact.min).map!(&:inspect)
+
entries[10] = '...' if entries.size == 11
"#<#{self.class.name} [#{entries.join(', ')}]>" I can create a pull request if this solution is acceptable. |
@htanata ,yeah, it only happens when inspect is used, but I think it can be better for inspect. |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Instead of loading all records and returning only a subset of those, just load the records as needed. Fixes rails#25537.
Steps to reproduce
Supposing we use MySQL and we have a model named "User" like this:
The table "users" have 100 million records in all.
When I use this query "User.find_in_batches", it generates a SQL:
"User Load (0.5ms) SELECT
users
.* FROMusers
" .And this will take a very very long time and occupy much memory.
However, it do work well with a "each" and a block followed:
The same problem with method "find_each".
So is this a bug?
Expected behavior
I expect this query "User.find_in_batches" to generate some SQL like this:
"User Load (0.4ms) SELECT
users
.* FROMusers
ORDER BYusers
.id
ASC LIMIT 1000"Actual behavior
Actually it generates a SQL and take a very very long time:
"User Load (0.5ms) SELECT
users
.* FROMusers
" .System configuration
Rails version:
Both Rails 4.2.6 and Rails v5.0.0.rc2.
Ruby version:
2.3.0
Script
Other Information and what I have tried
I try to find the solution to this problem.And these are what I have done:
1, I read the source code(Rails 4.2.6) of this method "find_in_batches":
And I found the problem is here:
2, Then I found that this "to_enum " method is from ruby "Object#to_enum", am I right?
But I cannot figure out what is the essence of this method.
3, I work with "pry", and I found that the problem really occurs here:
Any help will be appreciated. Thanks!
The text was updated successfully, but these errors were encountered: