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