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

时间:2014-04-23 04:29:07

标签: mongodb

我正在尝试使用mongodb后端编写一个更简单的会话(如果重要的话,使用haskell驱动程序)。我可能错了,但与我在没有会话的情况下运行替补席时相比,似乎有点慢。 通过会话,它每秒给我25个连接 - 10596没有。

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

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

我在本文档test if document exists中发现,使用findlimit进行测试的速度更快。但它只将其与findOne进行比较 - 而不是count

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

感谢。

1 个答案:

答案 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
}

如果这仍然不符合您的要求,您需要尝试分析瓶颈所在。如果有必要,这是我们可以讨论的另一个话题。