MongoDb documentation提供了一个库存项目示例,用于解释为什么键的顺序对性能有重要影响。
它提供了一个示例数据集:
{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 }
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 }
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 }
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 }
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 }
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 }
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 }
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 }
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 }
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }
它比较了2个相似复合指数的表现。请注意,键的顺序是相反的,以指出要点:
db.inventory.createIndex( { quantity: 1, type: 1 } )
db.inventory.createIndex( { type: 1, quantity: 1 } )
它使用第一个索引执行查询:
db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ quantity: 1, type: 1 }).explain("executionStats")
对于第一个索引,文档说明:
"totalKeysExamined" : 5,
"totalDocsExamined" : 2,
然后,查询第二个索引:
db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ type: 1, quantity: 1 }).explain("executionStats")
显示结果:
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
最后,结论是:
对于此示例查询,复合索引{type:1,quantity:1}比复合索引{quantity:1,type:1}更有效。
如果数据多食品项目和少数项目满足数量范围,或者反之亦然,我可以看到订单如何影响效果。但是,我认为这与文档中的要点不同。
有5个项目满足数量要求。有4种满足类型要求。我不明白第二个索引在第一个索引中如何导致totalKeysExamined为2对5。我看到4种食物。所以,我的直觉告诉我它的4对5。
希望,一些额外的解释可以解决我的困惑。我想完全理解复合索引键顺序的重要性。
感谢。
编辑:
我现在看到了。它有助于在不同场景下可视化2个列表。
以下是按类型列出的数据,然后是数量:
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 }
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 }
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 }
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 }
{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 }
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 }
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 }
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 }
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 }
以下是数量列表,然后输入:
{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 }
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 }
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 }
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 }
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 }
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 }
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 }
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 }
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 }
继续Veeram的评论,似乎与前一个指数一样,我们只需要点击指数一次就可以找到所需数量的食物。一旦我们降落,我们就按顺序迭代。但是,如果我们必须首先查看数量,我们将混合使用多种不同类型,因此我们必须跳过其他类型才能获得食物。