jlh*_*awn 16 performance profiling eval mongodb pymongo
我需要对需要在数组中旋转一些值的文档执行更新操作.MongoDB的更新查询目前不允许你$pop,然后$push在更新同一领域.在网上搜索建议后,我认为db.eval()最适合我的使用,因为它确保了原子性,我正在执行的操作非常短,因此它不会长时间锁定数据库.
这是我正在尝试做的事情的一个例子:
db.eval(function (id, newVal) {
doc = db.collection.findOne({_id: id});
doc.values.shift();
doc.values.push(newVal);
db.collection.save(doc);
}, id, newVal);
Run Code Online (Sandbox Code Playgroud)
这完美地运作!然后我启用了mongoDB分析,看看eval()命令花了多少毫秒,我总是得到少于1毫秒的结果:
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 0 }
{ "millis" : 0 }
...
Run Code Online (Sandbox Code Playgroud)
这对我来说是个好消息,除了我的应用程序是在python中,所以我使用pymongo客户端来执行eval()命令.(上面的数据来自mongo shell)但现在,当我eval()使用pymongo 运行相同的命令时:
conn = pymongo.Connection(mongo_server_hostname)
db = conn.my_db
db.eval("""function (id, newVal) {
doc = db.collection.findOne({_id: id});
doc.values.shift();
doc.values.push(newVal);
db.collection.save(doc);
}""", id, new_val)
Run Code Online (Sandbox Code Playgroud)
我得到了非常不同的分析结果:
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 13 }
{ "millis" : 14 }
{ "millis" : 14 }
...
Run Code Online (Sandbox Code Playgroud)
eval()从mongo shell和pymongo中运行相同的命令有什么根本不同的结果导致服务器从pymongo运行相同的命令需要多花14ms?
您所看到的差异的一个可能原因(但不一定是原因)是mongoshell 和mongod服务器默认情况下都使用 Google 的 v8 Javascript 引擎(尽管可以将其配置为使用 Spidermonkey 作为替代方案)来解释命令你给。
Google 的 v8 看到了 Javascript 代码中的热点,并且很可能是经常使用的 JIT 代码。
另一方面,普通的 PyMongo 是用纯 Python 编写的,这意味着它将始终被解释,这会产生相当大的开销。
如果您还没有这样做,一种可能是使用用 C 编写的 PyMongo 扩展而不是默认扩展,或者,如果应用程序的其余部分兼容,则使用 Python 的 PyPy JIT 解释器。
如果您使用任何源自 Debian 的发行版(例如 Ubuntu),python-pymongo-ext包将为您提供 PyMongo C 版本的预编译版本。
| 归档时间: |
|
| 查看次数: |
3593 次 |
| 最近记录: |