我们需要按照与查询参数相同的顺序创建一个复合索引。这个命令对性能有影响吗?
假设我们有一个地球上所有人类的集合,其索引在
如果我们希望能够用某个
雷德桑德罗,
您必须考虑
索引基数指的是字段可能有多少个值。字段
>
如果您有一个关于 null null 此外,您希望有选择地使用索引,并编写查询,以限制具有索引字段的可能文档的数量。为了保持简单,请考虑下面的集合。如果您的索引是 请考虑以下集合。如果您的索引是 想象一下在一个更大的数据集上可能存在的差异。 很容易对复合索引做出错误的假设。根据MongoDB关于复合索引的文档。 MongoDB支持复合索引,即单个索引结构保存对集合文档中多个字段的引用。下图说明了两个字段上的复合索引示例: 创建复合索引时,1个索引将包含多个字段。因此,如果我们按 如果我们按 使用。您必须扫描
{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}
{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}
["male","Rick"] -> 0x0c965148
["male","John"] -> 0x0c965149
["male","Sean"] -> 0x0cdf7859
["male","Bro"] ->> 0x0cdf7859
...
["female","Kate"] -> 0x0c965134
["female","Katy"] -> 0x0c965126
["female","Naji"] -> 0x0c965183
["female","Joan"] -> 0x0c965191
["female","Sara"] -> 0x0c965103
["John","male"] -> 0x0c965148
["John","female"] -> 0x0c965149
["John","male"] -> 0x0cdf7859
["Rick","male"] -> 0x0cdf7859
...
["Kate","female"] -> 0x0c965134
["Katy","female"] -> 0x0c965126
["Naji","female"] -> 0x0c965183
["Joan","female"] -> 0x0c965191
["Sara","female"] -> 0x0c965103
我要说的是,我自己做了一个实验,发现首先使用区分性差的索引键似乎没有性能损失。(我正在使用MongoDB3.4和wiredtiger,它可能与mmap不同)。我将2.5亿个文档插入到一个名为
{
field1:"bob",
field2:i + "",
field3:i + ""
`db.items.createIndex({field1:1,field2:1})`
当然,field1在每个文档上都是“Bob”,因此索引应该在找到所需文档之前搜索许多项。然而,这并不是我得到的结果。
在索引创建完成后,我对集合进行了另一次搜索。这一次,我得到的结果,我列出了下面。您将看到
{
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 4,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
...
"docsExamined" : 1,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
...
"indexName" : "field1_1_field2_1",
"isMultiKey" : false,
...
"indexBounds" : {
"field1" : [
"[\"bob\", \"bob\"]"
],
"field2" : [
"[\"250888000\", \"250888000\"]"
]
},
"keysExamined" : 1,
"seeks" : 1
}
}
然后我在
db.items.find(Field3:250888000);
与复合指数法相同,用时4ms。我用field2和field3的不同值重复了多次,每次都得到了不显著的差异。这表明,使用wiredtiger,索引的第一个字段的差分不会导致性能损失。