gpt4 book ai didi

mongodb - 多键索引上的慢范围查询

转载 作者:IT老高 更新时间:2023-10-28 13:29:16 26 4
gpt4 key购买 nike

我有一个名为 post 的 MongoDB 集合,其中包含 3500 万 个对象。该集合有两个二级索引,定义如下。

> db.post.getIndexKeys()
[
{
"_id" : 1
},
{
"namespace" : 1,
"domain" : 1,
"post_id" : 1
},
{
"namespace" : 1,
"post_time" : 1,
"tags" : 1 // this is an array field
}
]

我希望以下查询(它仅按 namespacepost_time 过滤)在合理的时间内运行而不扫描所有对象。

>db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).count()
7408

然而,MongoDB 至少需要十分钟来检索结果,而且奇怪的是,它设法根据 explain 函数扫描 7000 万 个对象来完成这项工作.

> db.post.find({post_time: {"$gte" : ISODate("2013-04-09T00:00:00Z"), "$lt" : ISODate("2013-04-09T01:00:00Z")}, namespace: "my_namespace"}).explain()
{
"cursor" : "BtreeCursor namespace_1_post_time_1_tags_1",
"isMultiKey" : true,
"n" : 7408,
"nscannedObjects" : 69999186,
"nscanned" : 69999186,
"nscannedObjectsAllPlans" : 69999186,
"nscannedAllPlans" : 69999186,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 378967,
"nChunkSkips" : 0,
"millis" : 290048,
"indexBounds" : {
"namespace" : [
[
"my_namespace",
"my_namespace"
]
],
"post_time" : [
[
ISODate("2013-04-09T00:00:00Z"),
ISODate("292278995-01--2147483647T07:12:56.808Z")
]
],
"tags" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost:27017"
}

物体个数和扫描个数的差异一定是标签数组的长度(都等于2)造成的。不过,我不明白为什么 post_time 过滤器不使用索引。

你能告诉我我可能缺少什么吗?

(我正在使用具有 24 核和 96 GB RAM 的下降机器。我使用的是 MongoDB 2.2.3。)

最佳答案

在这个问题中找到了我的答案:Order of $lt and $gt in MongoDB range query

我的索引是一个多键索引(在 tags 上)并且我正在运行一个范围查询(在 post_time 上)。 Apparently , 在这种情况下,MongoDB 不能使用范围的两边作为过滤器,所以它只选择 $gte 子句,它是第一个出现的。由于我的下限恰好是最低 post_time 值,MongoDB 开始扫描所有对象。

不幸的是,这并不是故事的全部。为了解决这个问题,我也创建了非多键索引,但 MongoDB 坚持使用坏的索引。这让我觉得问题出在其他地方。最后,我不得不删除多键索引并创建一个没有 tags 字段的索引。现在一切都很好。

关于mongodb - 多键索引上的慢范围查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16460471/

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