按 ISODate 聚合查询性能排序
aggregate query performance sorting by ISODate
我有这种简单的聚合查询
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someISODatePropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
此查询 returns 最多 50 个项目,需要 10 秒才能完成。
如果我只是将排序 属性 更改为数字:
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someNumericPropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
查询需要几毫秒才能完成。
ISODate 属性是否存在任何排序问题?
我真的不明白为什么第一个版本要花这么长时间。
谢谢。
更新
这是"explain"标志设置为true的查询结果(注意:在ISODate字段上有一个索引):
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"StreamId" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
},
"sort" : {
"CommitStamp" : 1
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "vrp-events-prod.Commits",
"indexFilterSet" : false,
"parsedQuery" : {
"StreamId" : {
"$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"StreamId" : {
"$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"CommitStamp" : 1
},
"indexName" : "CommitStamp_Index",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"CommitStamp" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : []
}
}
},
{
"$unwind" : {
"path" : "$Events"
}
}
],
"ok" : 1
}
根据我的经验,日期字段上没有索引的日期排序很慢。假设您经常阅读此 collection 并且通常按日期排序,添加索引将是理想的解决方案。
db.collection.createIndex("someISODatePropertyName": 1 或 -1)
尝试一下,它总是对我产生巨大的影响。
更新:
假设这不会大大降低您的写入查询速度,请添加一个涵盖匹配和排序的索引:
db.xxx.createIndex({"StreamId": 1, "CommitStamp": 1});
我在我的 collection 上测试了它,它将查询从 15 秒(使用日期索引)加速到不到一秒(使用新创建的索引)。仅供参考,我更新的解释显示:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.xxx",
"indexFilterSet" : false,
"parsedQuery" : {
"id" : {
"$eq" : 122
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"id" : 1,
"date" : 1
},
"indexName" : "id_1_date_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[122.0, 122.0]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
}
我有这种简单的聚合查询
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someISODatePropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
此查询 returns 最多 50 个项目,需要 10 秒才能完成。
如果我只是将排序 属性 更改为数字:
db.SomeCollection.aggregate([{
"$match": {
"Id": "someId"
}
}, {
"$sort": {
"someNumericPropertyName": 1
}
}, {
"$unwind": {
"path": "$somePropertyName"
}
}], {
allowDiskUse: true
})
查询需要几毫秒才能完成。
ISODate 属性是否存在任何排序问题?
我真的不明白为什么第一个版本要花这么长时间。
谢谢。
更新
这是"explain"标志设置为true的查询结果(注意:在ISODate字段上有一个索引):
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"StreamId" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
},
"sort" : {
"CommitStamp" : 1
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "vrp-events-prod.Commits",
"indexFilterSet" : false,
"parsedQuery" : {
"StreamId" : {
"$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"StreamId" : {
"$eq" : "5b8cc895-c626-5994-95d4-b9ac89fb66ed"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"CommitStamp" : 1
},
"indexName" : "CommitStamp_Index",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"CommitStamp" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : []
}
}
},
{
"$unwind" : {
"path" : "$Events"
}
}
],
"ok" : 1
}
根据我的经验,日期字段上没有索引的日期排序很慢。假设您经常阅读此 collection 并且通常按日期排序,添加索引将是理想的解决方案。
db.collection.createIndex("someISODatePropertyName": 1 或 -1)
尝试一下,它总是对我产生巨大的影响。
更新:
假设这不会大大降低您的写入查询速度,请添加一个涵盖匹配和排序的索引:
db.xxx.createIndex({"StreamId": 1, "CommitStamp": 1});
我在我的 collection 上测试了它,它将查询从 15 秒(使用日期索引)加速到不到一秒(使用新创建的索引)。仅供参考,我更新的解释显示:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.xxx",
"indexFilterSet" : false,
"parsedQuery" : {
"id" : {
"$eq" : 122
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"id" : 1,
"date" : 1
},
"indexName" : "id_1_date_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[122.0, 122.0]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
}