我创建了一个包含100个文档(字段x
& y
)的集合,并在字段x
上创建了一个普通索引,在字段y
上创建了一个稀疏索引,如下图所示:
for(i=1;i<100;i++)db.coll.insert({x:i,y:i})
db.coll.createIndex({x:1})
db.coll.createIndex({y:1},{sparse:true})
然后,我添加了一些没有字段的文档x&amp;如下图所示:
for(i=1;i<100;i++)db.coll.insert({z:"stringggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"})
查看db.coll.stats()
,我找到了索引的大小:
storageSize:36864
_id:32768
x_1:32768
y_1:16384
根据稀疏索引的定义,只考虑包含索引字段y
的文档,因此y_1
占用的空间更少。但是_id
&amp; x_1
索引似乎包含其中的所有文档。
如果我执行查询 - db.coll.find({z:99}).explain('executionStats')
它正在执行COLLSCAN并获取记录。如果是这种情况,我不清楚为什么MongoDB将所有文件存储在_id
&amp; x_1
索引,因为它浪费了存储空间。请帮我理解。请原谅我的无知,如果我错过了什么。
感谢您的帮助。
答案 0 :(得分:3)
在&#34;正常&#34;索引,缺少的字段使用null
值编制索引。例如,如果索引为{a:1}
并且您将{b:10}
插入集合中,则该文档将被编入索引为a: null
。
您可以使用唯一索引查看此行为:
> db.test.createIndex({a:1}, {unique:true})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.test.insert({b:1})
WriteResult({ "nInserted" : 1 })
> db.test.insert({c:1})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.test index: a_1 dup key: { : null }"
}
})
{b:1}
和{c:1}
都被编入索引a: null
,因此出现重复的密钥错误消息。
在您的收藏中,您有200份文件:
{x:..., y:...}
{z:...}
您的索引是:
{x:1}
(正常指数){y:1}
(稀疏索引)文件将编入索引如下:
_id
索引中,该索引始终由MongoDB {x:1}
索引中,来自{x:.., y:..}
和{z:..}
个文档{y:1}
索引请注意,您发布的索引尺寸显示与上述数字相同的比率。
关于你的问题:
_id
索引用于MongoDB内部使用,请参阅Default _id index。您不能删除此索引,并尝试删除它可能导致您的数据库无法访问。x_1
索引是因为您告诉MongoDB构建它。它包含集合中的所有文档,因为它是正常索引。对于您的集合,索引中的一半值为null
。y_1
索引的大小是x_1
索引的一半,因为200个文档中只有100个包含y
字段。db.coll.find({z:99})
不使用任何索引,因为您在z
字段上没有索引,因此它正在进行收集扫描。有关建立索引的详细信息,请参阅Create Indexes to Support Your Queries