如何解决缓慢的 MongoDB 查询
我是 MongoDB 的新手,并试图了解为什么我的查询如此缓慢(每个查询 30-150 秒!)。我的数据库包含大约 6000 万个文档。在我的查询中,我需要结合参数搜索和全文搜索。这是我要分析的查询:
db.collection.explain("executionStats").find(
{"property.multi.value_title": "Pearson Education (US)","pricing.price" : {$gte: 70,$lte: 600},$text: { $search: "app" }
}).count()
这是解释结果:
{
"queryPlanner" : {
"plannerVersion" : 1,"namespace" : "test.collection","indexFilterSet" : false,"parsedQuery" : {
"$and" : [
{
"property.multi.value_title" : {
"$eq" : "Pearson Education (US)"
}
},{
"pricing.price" : {
"$lte" : 600
}
},{
"pricing.price" : {
"$gte" : 70
}
},{
"$text" : {
"$search" : "app","$language" : "none","$caseSensitive" : false,"$diacriticSensitive" : false
}
}
]
},"winningPlan" : {
"stage" : "COUNT","inputStage" : {
"stage" : "FETCH","filter" : {
"$and" : [
{
"pricing.price" : {
"$lte" : 600
}
},{
"pricing.price" : {
"$gte" : 70
}
},{
"property.multi.value_title" : {
"$eq" : "Pearson Education (US)"
}
}
]
},"inputStage" : {
"stage" : "TEXT","indexPrefix" : {
},"indexName" : "translate.cs.content_text","parsedTextQuery" : {
"terms" : [
"app"
],"negatedTerms" : [ ],"phrases" : [ ],"negatedPhrases" : [ ]
},"textIndexVersion" : 3,"inputStage" : {
"stage" : "TEXT_MATCH","inputStage" : {
"stage" : "FETCH","inputStage" : {
"stage" : "OR","inputStage" : {
"stage" : "IXSCAN","keyPattern" : {
"_fts" : "text","_ftsx" : 1
},"isMultiKey" : true,"isUnique" : false,"isSparse" : false,"isPartial" : false,"indexVersion" : 2,"direction" : "backward","indexBounds" : {
}
}
}
}
}
}
}
},"rejectedPlans" : [ ]
},"executionStats" : {
"executionSuccess" : true,"nReturned" : 0,"executionTimeMillis" : 29794,"totalKeysExamined" : 7996,"totalDocsExamined" : 15992,"executionStages" : {
"stage" : "COUNT","executionTimeMillisEstimate" : 27400,"works" : 7997,"advanced" : 0,"needTime" : 7996,"needYield" : 0,"saveState" : 1220,"restoreState" : 1220,"isEOF" : 1,"nCounted" : 6,"nSkipped" : 0,"nReturned" : 6,"advanced" : 6,"needTime" : 7990,"docsExamined" : 7996,"alreadyHasObj" : 7996,"nReturned" : 7996,"executionTimeMillisEstimate" : 27390,"advanced" : 7996,"needTime" : 0,"docsRejected" : 0,//HERE
"executionTimeMillisEstimate" : 27380,"alreadyHasObj" : 0,"executionTimeMillisEstimate" : 175,"dupsTested" : 7996,"dupsDropped" : 0,"executionTimeMillisEstimate" : 165,"indexBounds" : {
},"keysExamined" : 7996,"seeks" : 1,"dupsDropped" : 0
}
}
}
}
}
}
}
},"serverInfo" : {
"host" : "ubuntu2004","port" : 27017,"version" : "4.4.1","gitVersion" : "ad91a93a5a31e175f5cbf8c69561e788bbc55ce1"
},"ok" : 1
}
我无法在文本索引中指定我的语言,因为我的 MongoDB 不支持它。
我正在查看 executionStats 部分的时间估计,我注意到在 IXSCAN
和 OR
操作之后,每个大约需要 170 毫秒,时间突然跳到 "executionTimeMillisEstimate" : 27380
在 FETCH
部分。
有人可以解释一下这是什么意思以及如何提高此查询的性能吗?
编辑:这些是我收藏的索引:
{
"v" : 2,"key" : {
"_id" : 1
},"name" : "_id_"
},{
"v" : 2,"key" : {
"_fts" : "text","_ftsx" : 1
},"name" : "translate.cs.content_text","default_language" : "none","language_override" : "none","weights" : {
"translate.cs.content" : 1
},"textIndexVersion" : 3
},"key" : {
"property" : 1
},"name" : "property_1"
},"key" : {
"property.multi.value_title" : 1
},"name" : "property.multi.value_title_1"
}
解决方法
您需要创建一个确保选择性的查询。为此,您可以创建一个 compound index。另外值得一提的是,您可以在文本索引中specified a language(默认为英文)
db.collection.createIndex(
{
property.multi.value_title: 1,field: "text",pricing.price: 1
},{ default_language: "spanish" }
)
对于复合索引,ESR 有助于决定索引中字段的顺序:
- 首先,添加运行 Equality 查询所针对的字段。
- 接下来要编入索引的字段应反映查询的排序顺序。
- 最后一个字段表示要访问的数据范围。
我的猜测是您的磁盘速度非常慢或内存不足,无法用于此工作负载。
- 如果您使用的是磁盘,请切换到 SSD。
- 如果您使用网络附加存储(例如所有 Amazon EBS),请提高您的网络速度(例如更改为“高 I/O”实例类型)。
- 为数据库提供更多内存。
查看 top
中的 I/O 等待时间以验证工作负载是否受 I/O 限制。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。