加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在shell shell与pymongo中的MongoDB db.eval()的性能

发布时间:2020-12-15 18:53:08 所属栏目:安全 来源:网络整理
导读:我需要对需要在数组中旋转某些值的文档执行更新操作. MongoDB更新查询当前不允许您弹出$pop,然后$push更新中的同一字段.在网上搜索建议之后,我决定db.eval()最适合我的使用,因为它确保原子性,并且我执行的操作非常短,所以它不会锁定数据库太久. 以下是我想要
我需要对需要在数组中旋转某些值的文档执行更新操作. 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);

这样做完美!然后,我启用了mongoDB分析,以查看eval()命令所用的毫秒数,我总是得到的结果少于1毫秒:

> db.system.profile.find({op: "command"},{"millis": 1}) 
 { "millis" : 0 }
 { "millis" : 0 }
 ...

对我来说这是个好消息,除了我的应用程序在Python中,所以我使用pymongo客户端来执行eval()命令. (上面的数据来自mongo shell)但是现在,当我使用pymongo运行相同的eval()命令时:

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);
}""",new_val)

我得到非常不同的分析结果:

> db.system.profile.find({op: "command"},{"millis": 1}) 
{ "millis" : 13 }
{ "millis" : 14 }
{ "millis" : 14 }
...

在mongo shell和pymongo中运行相同的eval()命令有什么根本不同的结果,导致服务器从pymongo运行相同的命令需要14ms?

您所看到的一个可能的原因(但不一定是原因),默认情况下是mongo shell和mongod server use Google’s v8 Javascript engine(尽管可以配置为使用Spidermonkey作为替代),以解释您给出的命令.

Google的v8会在Javascript代码中看到热点,并且可能会经常使用JIT代码.

另一方面,香草PyMongo是written in pure Python,这意味着它将永远被解释,这是一个相当大的开销.

如果您还没有这样做,一个可能的办法是使用PyMongo extension written in C而不是默认的,或者如果您的其他应用程序兼容,则使用Python的PyPy JIT解释器.

如果您使用从Debian(如Ubuntu)派生的任何发行版,则python-pymongo-ext软件包可为您提供PyMongo的C版本的预编译版本.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读