mongoDB没有选择索引
Posted
技术标签:
【中文标题】mongoDB没有选择索引【英文标题】:mongoDB not picking index 【发布时间】:2022-01-21 23:39:06 【问题描述】:我有一个如下的 mongoDB 查询。
db.mobiles.find(
$or: [
status: "roaming"
,
status: "local"
,
inUse: true
,
available: true
,
color: true
],
updatedAt:
$lte: 1639992579831
)
我创建了如下索引
db.mobiles.createIndex( “status” : 1 , “inUse” : 1 , “available” : 1 , “color” : 1 , “updatedAt” : -1 )
当我执行 explain() 时,我没有看到索引被使用。难道我做错了什么。 ?
我可以看到在我执行db.mobiles.getIndexes()
时创建了索引
【问题讨论】:
【参考方案1】:https://docs.mongodb.com/manual/core/index-compound/#prefixes 读作:
对于复合索引,MongoDB 可以使用索引来支持对索引前缀的查询。
db.mobiles.createIndex( “status” : 1 , “inUse” : 1 , “available” : 1 , “color” : 1 , “updatedAt” : -1 )
是一个复合索引,因此唯一可以从中受益的查询是至少具有“状态”谓词的查询。
您的查询确实有它,但在 $or 语句中,意味着您很乐意选择具有 status
的文档,只要至少有 1 个其他 $or 条件匹配,例如颜色。在这种情况下,mongo 无法使用该字段在索引中进行搜索。
这是它在 explain() 输出中的样子:
"parsedQuery":
"$and": [
"$or": [
"$or": [
"available":
"$eq": true
,
"color":
"$eq": true
,
"inUse":
"$eq": true
]
,
"status":
"$in": [
"local",
"roaming"
]
]
,
"updatedAt":
"$lte": 1639992579831
]
,
但这不是故事的全部。查询计划器分析诸如索引选择性之类的参数。考虑到它是一个布尔值,没有太多选项,并且对于正态分布,它必须像一半的集合符合条件。在这种情况下使用索引并没有太大的好处。
考虑到查询,唯一有意义的索引是updatedAt:
db.mobiles.createIndex( “updatedAt” : -1 )
【讨论】:
以上是关于mongoDB没有选择索引的主要内容,如果未能解决你的问题,请参考以下文章
最简单方式理解为什么MongoDB索引选择B-树,而 Mysql 选择B+树