我一直在处理mongo数据库中的一个问题,我对其在索引上的选择感到困惑。
我有一个大约有3500万条记录和2个复合索引的集合。这两个索引都适合mongo缓存。
当我去调查问题时,索引看起来像这样:
{
"v" : 2,
"key" : {
"recType" : 1,
"tstamp" : -1
},
"name" : "recType_1_tstamp_-1",
"ns" : "example.objs",
"background" : true
},
{
"v" : 2,
"key" : {
"recType" : 1,
"data.time" : -1
},
"name" : "rectype_1_data.time_-1",
"ns" : "example.objs",
"background" : true
}
我们挂了一些查询。查询看起来像这样:
db.objs.find({ "recType": "someType", "tstamp": { $gte: NumberLong(1529078246476) } }).count()
这些将运行数小时而不会返回。通过检查currentOp,我注意到查询使用的索引是
rectype_1_data.time_-1
考虑到发现中指定的字段上存在复合索引,我认为这很奇怪。然后,我用提示运行查询:
db.objs.find({ "recType": "someType", "tstamp": { $gte: NumberLong(1529078246476) } }).hint("recType_1_tstamp_-1").count()
这条跑了大约1秒钟。所以我的第一个问题是,mongo为什么会在这里选择错误的索引?关于查询是否有一些混淆之处?有一些内部数据可以清除吗?
接下来,由于我不想一直使用提示运行它,所以我创建了一个相似的索引,第二个键指向另一个方向:
{
"v" : 2,
"key" : {
"recType" : 1,
"tstamp" : 1
},
"name" : "recType_1_tstamp_1",
"ns" : "example.objs",
"background" : true,
}
现在,已经为上述查询正确选择了该索引(无需提示)。
我的第二个问题是,此特定键和查询的索引中第二个键的顺序是否重要?我的理解是,这不重要。
我不满意将此作为解决方案保留在数据库中,却不理解为什么要做出这些选择。谢谢!