在日志中我发现查询很慢,但是手动运行它们时速度很快,或者至少考虑到索引。
日志告诉我查询部分没有使用可用的索引。
运行查询会考虑索引。
在 AWS DocumentDB(与 MongoDB 3.6 大部分兼容)上运行。
日志告诉我这一点(互联网的匿名字段名称 ;-)):
{"op":"update",
"ts":1578041832906,
"ns":"collection",
"command":{
"q":{"array.field1":{"$binary":"Hzy2Q0TBYEAWadeCtxpXuA==","$type":"3"}},
"u":{"$set":{"array.$.field2":174}}},
"nMatched":0,
"nModified":0,
"protocol":"op_query",
"millis":694,
"planSummary":"IXSCAN",
"execStats":{
"stage":"UPDATE",
"nReturned":"0",
"executionTimeMillisEstimate":"694.497",
"inputStages":[{
"stage":"LIMIT_SKIP",
"nReturned":"0",
"executionTimeMillisEstimate":"694.488",
"inputStage":{
"stage":"COLLSCAN",
"nReturned":"0",
"executionTimeMillisEstimate":"694.486"
}
},{
"stage":"IXSCAN",
"nReturned":"0",
"executionTimeMillisEstimate":"694.492",
"indexName":"_idDocField3",
"direction":"forward"
}]
},
}
在更新上对此进行解释时
collection.explain().update(
{"array.field1": BinData(3, "Hzy2Q0TBYEAWadeCtxpXuA==")},
{$set: {"array.$.field2":174}}
)
queryPlanner 向我展示了这个
{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "collection",
"winningPlan": {
"stage": "UPDATE",
"inputStages": [
{
"stage": "LIMIT_SKIP",
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"indexName": "arrayField1"
}
}
},
{
"stage": "IXSCAN",
"indexName": "_idDocField3",
"direction": "forward"
}
]
}
},
"serverInfo": {
"host": "xxxxxxx",
"port": 27017,
"version": "3.6.0"
},
"ok": 1
}
可用的索引有:
_id_ { _id:1 }, ops: ~56,000
,_idDocField3 { _id: 1, docField3: 1 }, ops: ~4,200,000
,arrayField1 { "array.field1": 1 }, ops: ~400
,arrayField1DocField3 { "array.field1": 1, docField3: 1 }, ops: 0
array
是一个包含文档的数组,id 是 UUID。
馆藏规模约为 40,000,000。
而且文档有点矛盾:
https://docs.mongodb.com/v3.6/core/index-multikey/
多键索引不能覆盖对数组字段的查询。但是,从 3.6 开始,如果 > > 索引跟踪哪个或哪些字段导致索引成为多键,则多键索引可以覆盖对非数组字段的查询。在 MMAPv1 以外的存储引擎上 > MongoDB 3.4 或更高版本中创建的多键索引会跟踪此数据。
是否可以删除复合索引并依赖索引交集?
或者切换复合索引的顺序?
谁能帮我优化这个?