gpt4 book ai didi

mongodb - MongoDB 如何选择候选计划

转载 作者:可可西里 更新时间:2023-11-01 10:21:50 26 4
gpt4 key购买 nike

我的应用程序查询速度很慢。创建两个索引后,它在本地数据库中使用它们具有更好的性能。但是当我部署到生产数据库时,它仍然使用原始索引。

下面是我所做的。

tasks 集合中的属性:team_idproject_idcreated_byassignee

查询如下所示

db.tasks.find({
team_id: new ObjectId(teamId),
$or: [
{
project_id: newObjectId(projectId),
created_by: userId
},
{
assignee: userId
}
]
})

最初只有一个针对 team_id 的索引,它将检查 10k 多个文档。然后我添加了两个新索引

project_1_created_by_1: {
project: 1,
created_by: 1
}

assignee_1: {
assignee: 1
}

在本地数据库中,我使用 explain({ verbose: true }) 运行查询。我可以看到 MongoDB 评估索引

[
QueryOptimizerCursor: [
'project_1_created_by_1',
'assignee_1',
],
BtreeCursor: 'team_1'
]

最终 QueryOptimizerCursor 获胜。

但是当我在生产 MongoDB 上运行它时,explain({ verbose: true }) 的结果显示它只评估了 team_1BasicCursor .

[
BtreeCursor: `team_1`,
BasicCursor
]

有没有人给我一些信息,为什么 MongoDB 没有使用我创建的新索引,更糟糕的是它没有评估它。

PS:我可以确认新索引已在我的生产数据库中准备就绪,因为当我使用查询 db.tasks.find({project: xxx, created_by:yyy}).explain() 时使用我创建的新的。

已更新

生产MongoDB的版本是2.4.12,本地是2.6.7。当我在本地安装 MongoDB 2.4.12 的新副本并运行相同的查询时,它使用 team 索引而不是 QueryOptimizerCursor

不太确定这是否只是因为 MongoDB 2.6.7 比 2.4.12 更智能。

最佳答案

如果集合中定义的多个索引可以满足查询,MongoDB 将并行测试所有适用的索引。查询计划器将选择第一个可以返回 101 个结果的索引。索引选择还有其他方面,但根据 Query Optimization 通常这是正确的文档。

这种索引选择方法可能会选择一个次优的索引。这是因为从 MongoDB 的角度来看,您有多个索引描述同一事物。要减轻您观察到的次优索引选择,您可以:

  1. 删除您发现的所有其他次优索引。

    这是为了确保查询规划器除了选择您为查询量身定制的索引外别无选择。

  2. 使用hint()方法

    hint() 允许您明确告诉 MongoDB 使用规定的索引进行查询。例如:

    db.tasks.find(...).hint({project: 1, created_by: 1})

    请参阅https://docs.mongodb.com/v2.6/reference/operator/meta/hint/有关 hint() 的更多信息。

查询中的另一个细微差别是它包含一个 $or 运算符。在这种情况下,$or 表达式中的每个术语都必须有一个与之关联的索引,否则 MongoDB 将执行集合扫描(BasicCursor in MongoDB 2.6 条款)。这在 https://docs.mongodb.com/v2.6/reference/operator/query/or/#behaviors 中有更详细的解释。

关于mongodb - MongoDB 如何选择候选计划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38427813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com