如果我使用提示,为什么Mongodb只使用我的索引
我有一个带有索引的ISODate()类型字段的数据库(我也用字符串字段尝试了这个实验-结果相同)。我使用的是开源版本的MongoDB(4.x),当我进行查询/排序以查找最大完成时间时,除非我指定了提示,否则不会使用索引 我的问题是:如果我使用提示,为什么Mongodb只使用我的索引,mongodb,performance,indexing,hint,Mongodb,Performance,Indexing,Hint,我有一个带有索引的ISODate()类型字段的数据库(我也用字符串字段尝试了这个实验-结果相同)。我使用的是开源版本的MongoDB(4.x),当我进行查询/排序以查找最大完成时间时,除非我指定了提示,否则不会使用索引 我的问题是: db.getCollection("test").find({}, { _finish_time: 1}).sort({_finish_time: -1}).limit(1) 其解释如下: { "queryPlanner" : { "pl
db.getCollection("test").find({}, { _finish_time: 1}).sort({_finish_time: -1}).limit(1)
其解释如下:
{
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "vdm-service-ts-staging.test",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_finish_time" : 1.0
},
"inputStage" : {
"stage" : "SORT",
"sortPattern" : {
"_finish_time" : -1.0
},
"limitAmount" : 1.0,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "COLLSCAN",
"direction" : "forward"
}
}
}
},
"rejectedPlans" : [
]
},
"serverInfo" : {
"host" : "ip-10-82-245-45.us-west-2.compute.internal",
"port" : 27017.0,
"version" : "4.0.1",
"gitVersion" : "54f1582fc6eb01de4d4c42f26fc133e623f065fb"
},
"ok" : 1.0,
"operationTime" : Timestamp(1573220526, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1573220526, 1),
"signature" : {
"hash" : BinData(0, "blIkiGcam87SDdbKeZKex/9JXBU="),
"keyId" : NumberLong(6715502669504446467)
}
}
}
扫描整个收藏。当我为可用索引指定提示时,如:
db.getCollection("test").find({}, { _finish_time: 1}).sort({_finish_time: -1}).limit(1).hint("_finish_time")
我得到了查询计划:
{
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "vdm-service-ts-staging.test",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "LIMIT",
"limitAmount" : 1.0,
"inputStage" : {
"stage" : "PROJECTION",
"transformBy" : {
"_finish_time" : 1.0
},
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_finish_time" : -1.0
},
"indexName" : "_finish_time",
"isMultiKey" : false,
"multiKeyPaths" : {
"_finish_time" : [
]
},
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 2.0,
"direction" : "forward",
"indexBounds" : {
"_finish_time" : [
"[MaxKey, MinKey]"
]
}
}
}
}
},
"rejectedPlans" : [
]
},
"serverInfo" : {
"host" : "ip-10-82-245-45.us-west-2.compute.internal",
"port" : 27017.0,
"version" : "4.0.1",
"gitVersion" : "54f1582fc6eb01de4d4c42f26fc133e623f065fb"
},
"ok" : 1.0,
"operationTime" : Timestamp(1573220603, 3),
"$clusterTime" : {
"clusterTime" : Timestamp(1573220603, 3),
"signature" : {
"hash" : BinData(0, "qsGhD1DpI306XbqtNZDYVINPid8="),
"keyId" : NumberLong(6715502669504446467)
}
}
}
它使用索引。我不想在我的查询中添加hint(),我对它为什么拒绝使用索引感到困惑
我的索引是稀疏的,不是唯一的
我尝试了其他索引并四处搜索,但在堆栈溢出或其他地方找不到与此问题相关的任何参考。根据MongoDB的文档 如果稀疏索引会导致查询的结果集不完整 和排序操作,MongoDB将不使用该索引,除非提示() 显式指定索引 要使用稀疏索引,请使用hint()显式指定索引
As hint()强制查询优化器在执行查询时使用索引这完全解释了我的问题,但这是违反直觉的。如果我添加了{u finish\u time:{$exists:true}对于我的查询,它确实使用了索引。由于排序和限制,他们似乎仍然可以使用此查询的索引。所有缺少该字段的记录在排序顺序中都是相同的。感谢帮助!@user3501690
\u finish\u time
上的稀疏索引将不包括没有\u finish\u time的文档代码>字段。阻止稀疏索引选择的正确性问题是,某些与“所有文档”的查询过滤器匹配的文档不会使用稀疏索引包含在内。