Mongodb 慢速会话:检查文档是否存在的最快方法

Mongodb 慢速会话:检查文档是否存在的最快方法,mongodb,Mongodb,我试图用mongodb后端编写一个更简单的会话(haskell驱动程序,如果有关系的话)。我可能错了,但与我在没有训练的情况下替补上场相比,这似乎有点慢。 与会话,它给了我25连接秒-10596没有 在初始加载上设置会话后,它所做的只是将cookie中的SID与mongodb中会话文档中存储的SID进行比较。因此,对于每个请求,它都会执行一次到数据库服务器的行程。我从cookie中获取SID,并检查mongodb中是否存在具有此类SID的文档。这就是全部。我正在学习,所以我的会话逻辑也可能关闭

我试图用mongodb后端编写一个更简单的会话(haskell驱动程序,如果有关系的话)。我可能错了,但与我在没有训练的情况下替补上场相比,这似乎有点慢。 与会话,它给了我25连接秒-10596没有

在初始加载上设置会话后,它所做的只是将cookie中的SID与mongodb中会话文档中存储的SID进行比较。因此,对于每个请求,它都会执行一次到数据库服务器的行程。我从cookie中获取SID,并检查mongodb中是否存在具有此类SID的文档。这就是全部。我正在学习,所以我的会话逻辑也可能关闭

目前,我使用
count
检查文档是否存在。我计算具有相关SID的文档,并测试它是否=1。这是检查文档是否存在的足够快的方法吗

我在本文档中发现,使用
find
limit
进行测试更快。但它只将其与
findOne
进行比较,而不是与
count
进行比较

所以我的问题是:检查文档是否存在的最快方法是什么


谢谢。

关于您的问题,请看一下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。
因此,我对以下三种方法进行了基准测试:

  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);
}
如果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
}

如果这仍然不能满足您的需求,您需要尝试分析瓶颈在哪里。这是另一个必要时我们可以讨论的话题。

您收集的数据有多少?您是否在字段SID上建立了索引?因为我是唯一连接到服务器的人,所以它只是一个会话条目-一个会话文档。文档的数量将等于连接了会话的用户的数量。也许基准测试工具会为每个连接创建一个新会话,这就是为什么它如此缓慢的原因。但是,不管我的会话问题如何,我仍然对检查文档是否存在的最快方法的通用答案感兴趣。如果您查看find/findOne/count的源代码,就会知道其中的区别:rs0:PRIMARY>db.geo.count function(x){return this.find(x.count();}谢谢。让我测试一下索引。目前索引位于“\u id”上。那么,使用
计数测试文档是否存在是否合适呢?我在上面添加了一个基准测试,结果表明计数是最慢的。看一看,好的。这基本上回答了这个问题。你得到了奖励。谢谢
{
  _id: [value of SID]
  ... // rest of record
}