【发布时间】:2018-04-17 19:42:55
【问题描述】:
我在 node js 中使用猫鼬驱动程序。我的架构:
let sendResultSchema = mongoose.Schema({
emailId: String, email: String,
letterId: String, sendedFrom: String,
resultMsg: String, owner: String,
created: Date, result: Boolean,
tag: String, tryNum: Number,
clickHash: String, links: [String]
})
sendResultSchema.index({emailId: 1, letterId: 1, result: 1, owner: 1, tag: 1, clickHash: 1})
let sendResultModel = mongoose.model('sendresult', sendResultSchema)
sendresult 集合有 641000 个文档。
此查询执行 ~0.5 秒。
db.sendresults.find({"tag" : "tagValue", "letterId" : "5ad630b5949bb02ea07d15d1"}).sort({emailId: -1}).limit(1)
我认为它必须执行得更快。你可以看到这个查询的解释here
如何让这个查询更快?
【问题讨论】:
-
sendResultSchema.index({tag: 1, letterId: 1, }); sendResultSchema.index({emailId: 1 });。然后阅读indexes。您不只是在每个字段上建立索引并期望它能够工作,这适用于每个数据库平台。您实际上需要将选择与您使用的查询模式相匹配。 -
@Neil 与
.index({ tag: 1, letterId: 1, emailId: -1})相比,您的建议表现如何?求朋友... ;) -
@john 在核心文档中有一个完整的“索引”部分,我还提供了一个链接。我建议你阅读每一页。核心是“查询”条件只能选择以查询(或排序)中存在的字段“前缀”的索引。仅仅因为索引包含字段,并不意味着它会被选中。因此,我的建议创建的索引将以所使用的字段为“前缀”。但手册中还有更多详细信息,以及其他关于一般索引的冗长博客文章和论文。
-
@john 阅读。排序是查询引擎可以使用不同索引的情况之一。
-
@john 您认为排序字段应该包含在复合索引中的印象是正确的。当排序操作需要与查询谓词完全分离的索引时,索引交集不适用:docs.mongodb.com/manual/core/index-intersection/…。 Optimizing MongoDB Compound Indexes 博客文章对阅读很有帮助。如果您有任何疑问,请使用
explain()确认查询计划器详细信息。