Strange performance issues with () vs find ()
Mongoid 3.1.6 Rails 3.2.21 MongoDB 2.4.9
We see 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
They both seem to be debugging the same queries. Can someone explain why we are seeing such a huge performance difference?
Configuration:
production:
sessions:
default:
uri: <%= REDACTED %>
options:
consistency: :strong
safe: true
max_retries: 1
retry_interval: 0
options:
identity_map_enabled: true
source to share
It appears to be find
using an identity mapping and where
not. If I set identity_map_enabled
to false
, then the performance of find
vs is where
identical.
Moral of the story: Use find
instead where
whenever possible.
I heard that the ID card was removed in Mongoid 4.x. Therefore, it is possible that this problem only affects people in older versions.
source to share
Here is my guess why the first one was several orders of magnitude slower (I am writing it from the Mongo point of view and do not know about the ruby).
The first time you run a query, it is not in the working set and this results in performance degradation. It has been there once in a row and therefore the performance is better. If you have a small number of documents, I would find this behavior odd (because I would expect them all to be in the working set).
The second part with $ is where it surprises me because I expect all numbers to be greater than c find()
(this is not the case with the first event) because:
The $ where function provides more flexibility, but requires the database to process a JavaScript expression or function for each document in the collection.
source to share