Reputation: 1721
Mongoid 3.1.6 Rails 3.2.21 MongoDB 2.4.9
We're seeing strange performance issues with find()
vs where().first
:
$ rails c
2.1.5 :001 > Benchmark.ms { User.find('5091e4beccbce30200000006') }
=> 7.95
2.1.5 :002 > Benchmark.ms { User.find('5091e4beccbce30200000006') }
=> 0.27599999999999997
2.1.5 :003 > Benchmark.ms { User.find('5091e4beccbce30200000006') }
=> 0.215
2.1.5 :004 > exit
$ rails c
2.1.5 :001 > Benchmark.ms { User.where(id: '5091e4beccbce30200000006').first }
=> 7.779999999999999
2.1.5 :002 > Benchmark.ms { User.where(id: '5091e4beccbce30200000006').first }
=> 4.84
2.1.5 :003 > Benchmark.ms { User.where(id: '5091e4beccbce30200000006').first }
=> 5.297
2.1.5 :004 > exit
These both appear to be firing off the same queries. Can someone explain why we're seeing such a huge difference in performance?
Configuration:
production:
sessions:
default:
uri: <%= REDACTED %>
options:
consistency: :strong
safe: true
max_retries: 1
retry_interval: 0
options:
identity_map_enabled: true
Upvotes: 4
Views: 539
Reputation: 1721
It appears that find
uses the identity map, while where
does not. If I set identity_map_enabled
to false
, then the performance of find
vs where
is identical.
Moral of the story: use find
instead of where
when possible.
I've heard that the identity map is removed in Mongoid 4.x. So maybe this issue only affects folks on older versions.
Upvotes: 0
Reputation: 222979
Here is my assumption why the first one was few orders of magnitude slower (I am writing it from mongo point of view and have zero knowledge about ruby).
The first time you fired the query it was not in the working set and this caused slower performance. The consecutive times it was already there and thus performance is better. If you have small number of documents, I would find this behavior strange (because I would expect that all of them would be in a working set).
The second part with $where surprises me because I would expect all the numbers be bigger than with find()
(it is not the case with the first event) because:
The $where provides greater flexibility, but requires that the database processes the JavaScript expression or function for each document in the collection.
Upvotes: 0