我有一系列课程,其中包含具有以下架构的文档
{
title: "Programming 101",
category: 1
likes: 10,
author: {
name: "Mike",
reputation: 100,
rating: 1500
},
created: 154895126, // unix timestamp
content: ".... html ... "
}
在我的应用程序的索引页面中,我显示了所有类别的最新18课程,所以这是
db.lessons.find().sort({created:-1}).limit(18)
由于这是一个非常常见的查询,而课程集将是我系统中最大的集合,我想尽可能地优化它,所以我在创建了
db.lessons.ensureIndex({created:-1})
但有时我想从一个类别中吸取教训
db.lessons.find({category:1}).sort({created:-1}).limit(18)
所以我也在类别中添加了一个索引,因为如果我不这样做,mongo可以轻松排序,但它仍然需要逐个元素检查以获得category = 1的那个,所以
db.lessons.ensureIndex({category:1})
因为我没有按类别排序,所以我只是传递1,以升序。
现在,问题是我还想根据喜欢,作者的声誉和作者的评级对课程进行排序,这些将是非常常见的任务,不像创建排序那样常见,但仍然很常见,我应该再增加3个索引?或者只使用创建的?
db.lessons.ensureIndex({likes:-1})
db.lessons.ensureIndex({'author.reputation':-1})
db.lessons.ensureIndex({'author.rating':-1})
我觉得我可能会使用太多的索引,内存中的集合大小可能很大。
答案 0 :(得分:4)
我将提出第三个asya关于综合指数的动议。
> db.lessons.ensureIndex({category:1});
> db.lessons.ensureIndex({created:-1});
> db.lessons.find({category:1}).sort({created:-1}).limit(18).explain();
{
"cursor" : "BtreeCursor category_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"scanAndOrder" : true,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"category" : [
[
1,
1
]
]
}
}
这里解释说明()说明MongoDB不会像我们预期的那样使用单个索引。
> db.lessons.ensureIndex({category:1,created:-1});
> db.lessons.find({category:1}).sort({created:-1}).limit(18).explain();
{
"cursor" : "BtreeCursor category_1_created_-1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"category" : [
[
1,
1
]
],
"created" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
}
}
总体指数看起来肯定是赢家。
至于对太多索引的关注,对于我的日常工作,我正在使用一个集合,该集合有超过3800万个文档,通过--notablescan选项禁用表扫描。我们发现,为每个查询定制索引至关重要。
答案 1 :(得分:0)
如果你提到
这些将是非常常见的任务
比我认为你应该使用索引,否则你的查询将在给出结果之前检查你的集合中的所有文档。当然,为了更准确地回答,必须知道你的收藏品的数量,当然还有一些关于“常见的东西”的指标。并且确定决定你应该如何表现的最好方法是进行一些测试。
收集用户在某段时间(2天)内的行为信息,并检查每种类型的查询出现的次数。比你现在的每个人的“共性”。比使用和不使用索引模拟这些类型的查询,并检查哪些更好。
我同意@Asya关于这里的回复
有没有理由你的第二个索引不是{category:1,created:-1}