Reputation: 3794
Lets assume i have hundred thousand users
Simple Example,
user = User.where(id: 1..10000)
User Load (30.8ms) SELECT `users`.* FROM `users` WHERE (`users`.`id` BETWEEN 1 AND 10000)
in here, i want to slice more like this,
user.where(id: 100..1000)
User Load (2.9ms) SELECT `users`.* FROM `users` WHERE (`users`.`id` BETWEEN 1 AND 10000) AND (`users`.`id` BETWEEN 100 AND 1000)
Why is active record hitting db twice? it already has result that has bigger data. why does it have to hit db, not just reuse and slice ActiveRecord::Relation?
Is there any good solution for this?
Upvotes: 0
Views: 228
Reputation: 576
Instead of making two iteration pass it in single:
User.where("id between ? and ?", 100,1000)
It will reduce the db hitting, hope its a answer for your question
Upvotes: 0
Reputation: 3870
ActiveRecord is hitting the db twice because you are running it in the console. This invokes the query on each line through .inspect
. If this was run within a block of code, invocation would be delayed till you actually access user
.
Upvotes: 0
Reputation: 176402
ActiveRecord keeps track of queries and is able to cache certain duplicate requests, but in this case it's not that immediate for a library to understand that the second one is a subset of the first.
Moreover, there are several reasons why a generic library such as ActiveRecord may not want to implement a caching logic like that one. Caching a large data set in a very large application may result into several Mb of memory, and processes may reach the memory limit of the machine fairly quickly because the garbage collector would not be able to recollect the memory.
Long story short, it's a very bad idea to implement such feature in a generic ORM library.
If you want to implement it in your own code, you are free to do it.
Upvotes: 2