我正在尝试使用mongodb后端编写一个更简单的会话(如果重要的话,使用haskell驱动程序)。我可能错了,但与我在没有会话的情况下运行替补席时相比,似乎有点慢。 通过会话,它每秒给我25个连接 - 10596没有。
在初始加载时设置会话后,它所做的只是将Cookie中的SID与存储在mongodb中的会话文档中的SID进行比较。因此,在每次请求时,它只执行一次数据库服务器。我从cookie获取SID并检查mongodb中是否存在具有此类SID的文档。这就是全部。我正在学习,所以我的会话逻辑也可以关闭。
目前,我使用count
检查文档是否存在。我计算具有相关SID的文档并测试它是否== 1.这是否足以检查文档是否存在?
我在本文档test if document exists中发现,使用find
和limit
进行测试的速度更快。但它只将其与findOne
进行比较 - 而不是count
。
所以我的问题是:检查文档是否存在的最快方法是什么?
感谢。
答案 0 :(得分:1)
关于你的问题,看一下find / findOne / count
的源代码rs0:PRIMARY> db.geo.count
function ( x ){
return this.find( x ).count();
}
rs0:PRIMARY> db.geo.findOne
function ( query , fields, options ){
var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/,
0 /* batchSize */, options);
if ( ! cursor.hasNext() )
return null;
var ret = cursor.next();
if ( cursor.hasNext() ) throw "findOne has more than 1 result!";
if ( ret.$err )
throw "error " + tojson( ret );
return ret;
}
rs0:PRIMARY> db.geo.find
function ( query , fields , limit , skip, batchSize, options ){
var cursor = new DBQuery( this._mongo , this._db , this ,
this._fullName , this._massageObject( query ) , fields , limit , skip , batchSize , options || this.getQueryOptions() );
var connObj = this.getMongo();
var readPrefMode = connObj.getReadPrefMode();
if (readPrefMode != null) {
cursor.readPref(readPrefMode, connObj.getReadPrefTagSet());
}
return cursor;
}
不同之处在于,findOne / count使用this.find中的内容,而find使用DBQuery 所以我在3种方式上做了基准测试:
function benchMark1() {
var date = new Date();
for (var i = 0; i < 100000; i++) {
db.zips.find({
"_id": "35004"
}, {
_id: 1
});
}
print(new Date() - date);
}
function benchMark2() {
var date = new Date();
for (var i = 0; i < 100000; i++) {
db.zips.findOne({
"_id": "35004"
}, {
_id: 1
});
}
print(new Date() - date);
}
function benchMark3() {
var date = new Date();
for (var i = 0; i < 100000; i++) {
db.zips.count({
"_id": "35004"
}, {
_id: 1
});
}
print(new Date() - date);
}
事实证明,benchMark1需要1046ms,2需要37611ms,3需要63306ms。 看来你使用的是最糟糕的一个 编辑:这里描述的原因很慢:https://dba.stackexchange.com/questions/7573/difference-between-mongodbs-find-and-findone-calls
还有什么,请确保您在字段SID上有unique index:
rs0:PRIMARY> db.system.indexes.find()
如果SID上没有索引,
rs0:PRIMARY> db.session.ensureIndex({SID: 1}, {unique: true}) // change "session" to your collection name
请注意,尽管_id通常是ObjectId,但并非必须如此。所以你可以使用SID作为_id。并且已经有一个索引,以便您可以保存索引,从而加快插入速度。为此,只需在插入记录时将_id字段设置为SID。
{
_id: [value of SID]
... // rest of record
}
如果这仍然不符合您的要求,您需要尝试分析瓶颈所在。如果有必要,这是我们可以讨论的另一个话题。