where() 与 find() 的奇怪性能问题
Strange Performance issues with where() vs find()
Mongoid 3.1.6
Rails 3.2.21
MongoDB2.4.9
我们发现 find()
与 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
这两个似乎都触发了相同的查询。谁能解释一下为什么我们看到如此巨大的性能差异?
配置:
production:
sessions:
default:
uri: <%= REDACTED %>
options:
consistency: :strong
safe: true
max_retries: 1
retry_interval: 0
options:
identity_map_enabled: true
这是我的假设,为什么第一个要慢几个数量级(我是从 mongo 的角度写的,对 ruby 的了解为零)。
您第一次启动查询时,它不在工作集中,这导致性能下降。它已经存在的连续时间因此性能更好。如果您的文档数量很少,我会发现这种行为很奇怪(因为我希望所有文档都在一个工作集中)。
$where 的第二部分让我感到惊讶,因为我希望所有数字都比 find()
大(第一个事件不是这种情况),因为:
The $where provides greater flexibility, but requires that the
database processes the JavaScript expression or function for each
document in the collection.
似乎 find
使用恒等映射,而 where
不使用。如果我将 identity_map_enabled
设置为 false
,那么 find
与 where
的性能是相同的。
故事的寓意:尽可能使用 find
而不是 where
。
我听说在 Mongoid 中删除了标识映射 4.x。所以也许这个问题只影响旧版本的人。
Mongoid 3.1.6 Rails 3.2.21 MongoDB2.4.9
我们发现 find()
与 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
这两个似乎都触发了相同的查询。谁能解释一下为什么我们看到如此巨大的性能差异?
配置:
production:
sessions:
default:
uri: <%= REDACTED %>
options:
consistency: :strong
safe: true
max_retries: 1
retry_interval: 0
options:
identity_map_enabled: true
这是我的假设,为什么第一个要慢几个数量级(我是从 mongo 的角度写的,对 ruby 的了解为零)。
您第一次启动查询时,它不在工作集中,这导致性能下降。它已经存在的连续时间因此性能更好。如果您的文档数量很少,我会发现这种行为很奇怪(因为我希望所有文档都在一个工作集中)。
$where 的第二部分让我感到惊讶,因为我希望所有数字都比 find()
大(第一个事件不是这种情况),因为:
The $where provides greater flexibility, but requires that the database processes the JavaScript expression or function for each document in the collection.
似乎 find
使用恒等映射,而 where
不使用。如果我将 identity_map_enabled
设置为 false
,那么 find
与 where
的性能是相同的。
故事的寓意:尽可能使用 find
而不是 where
。
我听说在 Mongoid 中删除了标识映射 4.x。所以也许这个问题只影响旧版本的人。