我有一系列课程,其中包含具有以下架构的文档
{
title: "Programming 101",
category: 1
likes: 10,
author: {
name: "Mike",
reputation: 100,
rating: 1500
},
created: 154895126, // unix timestamp
content: ".... html ... "
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序的索引页中,我显示了所有类别的最新 18 节课程,所以这是
db.lessons.find().sort({created:-1}).limit(18)
Run Code Online (Sandbox Code Playgroud)
由于这是一个非常常见的查询,并且课程集合将是我在系统中最大的集合,我想尽可能地优化它,所以我在创建的索引上创建了索引
db.lessons.ensureIndex({created:-1})
Run Code Online (Sandbox Code Playgroud)
但有时我只想从某一类别中吸取教训
db.lessons.find({category:1}).sort({created:-1}).limit(18)
Run Code Online (Sandbox Code Playgroud)
所以我还在category中添加了一个索引,因为如果我不这样做,mongo可以轻松排序,但它仍然需要逐个元素检查以获得category = 1的索引,所以
db.lessons.ensureIndex({category:1})
Run Code Online (Sandbox Code Playgroud)
因为我不按类别排序,所以我只传递 1,表示升序。
现在的问题是我还想按喜欢、作者声誉和作者评级对课程进行排序,这些将是非常常见的任务,不像按创建排序那么常见,但仍然很常见,我应该再添加 3 个索引吗?或者只使用创建的一个?
db.lessons.ensureIndex({likes:-1})
db.lessons.ensureIndex({'author.reputation':-1})
db.lessons.ensureIndex({'author.rating':-1})
Run Code Online (Sandbox Code Playgroud)
我觉得我可能使用了太多索引,并且内存中的集合大小可能很大。
我将赞同阿西亚提出的关于综合指数的动议。
> 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
]
]
}
}
Run Code Online (Sandbox Code Playgroud)
这里的explain()说明了MongoDB不会像我们期望的SQL数据库那样利用这两个单独的索引。
> 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
}
]
]
}
}
Run Code Online (Sandbox Code Playgroud)
综合指数看起来肯定是赢家。
至于对太多索引的担忧,在我的日常工作中,我正在处理一个包含超过 3800 万个文档的集合,并且通过 --notablescan 选项禁用了表扫描。我们发现为每个查询量身定制索引对我们来说至关重要。
| 归档时间: |
|
| 查看次数: |
3137 次 |
| 最近记录: |