users
馆藏有2000000个文档。
users
模式在这里。
MongoDB> db.users.find().limit(1).pretty()
{
"_id" : ObjectId("5d09e3d6ffe466000e1006e1"),
"created_at" : ISODate("2019-06-19T07:07:24Z"),
"updated_at" : ISODate("2019-06-19T07:27:17Z"),
"user_id" : NumberLong(2141055),
"nickname" : "john",
"birthday" : ISODate("1992-08-02T00:00:00Z"),
"gender" : "M",
"region" : "US",
"is_fake" : false,
"is_block" : false,
"is_out" : false,
"is_introduce_disable" : true,
"final_score" : 40
}
我必须通过具有多种过滤条件的distinct()提取user_id
。
过滤条件
所以我首先创建索引。
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.users"
},
{
"v" : 2,
"unique" : true,
"key" : {
"user_id" : 1
},
"name" : "user_id_1",
"ns" : "test.users"
},
{
"v" : 2,
"key" : {
"nickname" : 1
},
"name" : "nickname_1",
"ns" : "test.users"
},
{
"v" : 2,
"key" : {
"birthday" : 1
},
"name" : "birthday_1",
"ns" : "test.users"
},
{
"v" : 2,
"key" : {
"is_out" : 1,
"is_fake" : 1,
"is_block" : 1,
"is_introduce_disable" : 1,
"birthday" : 1,
"gender" : 1,
"final_score" : 1
},
"name" : "is_out_1_is_fake_1_is_block_1_is_introduce_disable_1_birthday_1_gender_1_final_score_1",
"ns" : "test.users"
}
]
并运行distinct()。
db.users.explain("executionStats").distinct(
"user_id",
{ "birthday": {
"$lte": ISODate("1992-06-08T00:00:00.000Z"),
"$gte": ISODate("1985-06-08T00:00:00.000Z")
},
"final_score": {
"$lte": 51.4,
"$gte": 10.73
},
"is_out": false,
"is_fake": false,
"is_block": false,
"is_introduce_disable": false,
"gender": "M"}
)
显然,这需要500毫秒。
所以我通过`explain()检查查询。
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"gender" : {
"$eq" : "M"
}
},
{
"is_block" : {
"$eq" : false
}
},
{
"is_fake" : {
"$eq" : false
}
},
{
"is_introduce_disable" : {
"$eq" : false
}
},
{
"is_out" : {
"$eq" : false
}
},
{
"birthday" : {
"$lte" : ISODate("1992-06-08T00:00:00Z")
}
},
{
"final_score" : {
"$lte" : 51.4
}
},
{
"birthday" : {
"$gte" : ISODate("1985-06-08T00:00:00Z")
}
},
{
"final_score" : {
"$gte" : 10.73
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"is_out" : 1,
"is_fake" : 1,
"is_block" : 1,
"is_introduce_disable" : 1,
"birthday" : 1,
"gender" : 1,
"final_score" : 1
},
"indexName" : "is_out_1_is_fake_1_is_block_1_is_introduce_disable_1_birthday_1_gender_1_final_score_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"is_out" : [ ],
"is_fake" : [ ],
"is_block" : [ ],
"is_introduce_disable" : [ ],
"birthday" : [ ],
"gender" : [ ],
"final_score" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"is_out" : [
"[false, false]"
],
"is_fake" : [
"[false, false]"
],
"is_block" : [
"[false, false]"
],
"is_introduce_disable" : [
"[false, false]"
],
"birthday" : [
"[new Date(487036800000), new Date(707961600000)]"
],
"gender" : [
"[\"M\", \"M\"]"
],
"final_score" : [
"[10.73, 51.4]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"gender" : {
"$eq" : "M"
}
},
{
"is_block" : {
"$eq" : false
}
},
{
"is_fake" : {
"$eq" : false
}
},
{
"is_introduce_disable" : {
"$eq" : false
}
},
{
"is_out" : {
"$eq" : false
}
},
{
"final_score" : {
"$lte" : 51.4
}
},
{
"final_score" : {
"$gte" : 10.73
}
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"birthday" : 1
},
"indexName" : "birthday_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"birthday" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"birthday" : [
"[new Date(487036800000), new Date(707961600000)]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 219815,
"executionTimeMillis" : 488,
"totalKeysExamined" : 224093,
"totalDocsExamined" : 219815,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 219815,
"executionTimeMillisEstimate" : 39,
"works" : 224093,
"advanced" : 219815,
"needTime" : 4277,
"needYield" : 0,
"saveState" : 1752,
"restoreState" : 1752,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 219815,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 219815,
"executionTimeMillisEstimate" : 17,
"works" : 224093,
"advanced" : 219815,
"needTime" : 4277,
"needYield" : 0,
"saveState" : 1752,
"restoreState" : 1752,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"is_out" : 1,
"is_fake" : 1,
"is_block" : 1,
"is_introduce_disable" : 1,
"birthday" : 1,
"gender" : 1,
"final_score" : 1
},
"indexName" : "is_out_1_is_fake_1_is_block_1_is_introduce_disable_1_birthday_1_gender_1_final_score_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"is_out" : [ ],
"is_fake" : [ ],
"is_block" : [ ],
"is_introduce_disable" : [ ],
"birthday" : [ ],
"gender" : [ ],
"final_score" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"is_out" : [
"[false, false]"
],
"is_fake" : [
"[false, false]"
],
"is_block" : [
"[false, false]"
],
"is_introduce_disable" : [
"[false, false]"
],
"birthday" : [
"[new Date(487036800000), new Date(707961600000)]"
],
"gender" : [
"[\"M\", \"M\"]"
],
"final_score" : [
"[10.73, 51.4]"
]
},
"keysExamined" : 224093,
"seeks" : 4278,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "localhost",
"port" : 27017,
"version" : "4.0.10",
"gitVersion" : "c389e7f69f637f7a1ac3cc9fae843b635f20b766"
},
"ok" : 1,
"operationTime" : Timestamp(1562132746, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562132746, 1),
"signature" : {
"hash" : BinData(0,"KZsayJye5mbXpHU9tB0i5RnWa9I="),
"keyId" : NumberLong("6706752768855506945")
}
}
}
在executionStats
中,
"nReturned" : 219815,
"executionTimeMillis" : 488,
"totalKeysExamined" : 224093,
"totalDocsExamined" : 219815,
似乎没问题。因为nReturned
和totalKeysExamined
之间没有太大区别。
您知道这需要将近488ms。但是在mysql中,它需要30毫秒。 (相同的环境)
问题
为什么在多条件搜索中MongoDB比MySQL慢?
winningPlans
和rejectedPlans
之间的确切区别是什么?
我的索引配置是否存在任何问题?
我的查询有任何建议吗?
谢谢!
答案 0 :(得分:0)
如果正在检查任何文档,则意味着它无法完全根据索引回答问题(在这种情况下,这是因为user_id
不在其使用的索引中)。