MongoDB-索引对排序影响

索引对排序的影响

如果排序的字段, 正好是索引的字段, 那么会大大提升排序效率。

插入测试数据:

db.person.insert([
{
name: 'cs',
age: 19
},
{
name: 'as',
age: 18
},
{
name: 'bs',
age: 17
}
])

插入完测试数据之后紧接着来进行一个排序的查询看看:

db.person.explain().find().sort({
name: 1
})

排序结果:

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.person",
"indexFilterSet" : false,
"parsedQuery" : {

},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"name" : 1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "COLLSCAN",
"direction" : "forward"
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "LAPTOP-A8CAC6IT",
"port" : 27017,
"version" : "4.0.28",
"gitVersion" : "af1a9dc12adcfa83cc19571cb3faba26eeddac92"
},
"ok" : 1
}

很明显是一个比没有创建索引的排序慢的,默认情况下,如果排序的不是索引字段,那么是在执行的时候再去排序,然后再输出,那么我们来将对应的索引进行创建一下:

db.person.createIndex({
name: 1
})

再次查询:

db.person.explain().find().sort({
name: 1
})

查询结果:

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.person",
"indexFilterSet" : false,
"parsedQuery" : {

},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "LAPTOP-A8CAC6IT",
"port" : 27017,
"version" : "4.0.28",
"gitVersion" : "af1a9dc12adcfa83cc19571cb3faba26eeddac92"
},
"ok" : 1
}

那么如果是多个字段进行排序呢:

db.person.explain().find().sort({
name: 1,
age: -1
})

查询结果:

{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "test.person",
"indexFilterSet": false,
"parsedQuery": {
},
"winningPlan": {
"stage": "SORT",
"sortPattern": {
"name": 1,
"age": -1
},
"inputStage": {
"stage": "SORT_KEY_GENERATOR",
"inputStage": {
"stage": "COLLSCAN",
"direction": "forward"
}
}
},
"rejectedPlans": []
},
"serverInfo": {
"host": "LAPTOP-A8CAC6IT",
"port": 27017,
"version": "4.0.28",
"gitVersion": "af1a9dc12adcfa83cc19571cb3faba26eeddac92"
},
"ok": 1
}

很明显没有走索引,这个时候就需要使用到我们之前所说的复合索引进行创建进行查询了,创建复合索引:

db.person.createIndex({
name: 1,
age: -1
})

排序查询:

db.person.explain().find().sort({
name: 1,
age: -1
})

查询结果:

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.person",
"indexFilterSet" : false,
"parsedQuery" : {

},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1,
"age" : -1
},
"indexName" : "name_1_age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ],
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[MinKey, MaxKey]"
],
"age" : [
"[MaxKey, MinKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "LAPTOP-A8CAC6IT",
"port" : 27017,
"version" : "4.0.28",
"gitVersion" : "af1a9dc12adcfa83cc19571cb3faba26eeddac92"
},
"ok" : 1
}

!> 如果是复合索引, 那么只有排序条件是前缀查询的形式才会使用索引来排序,例如, 复合件索引只支持前缀子查询, 也就是 A,B,C 复合索引, A,B,C 会使用索引, A,B 会使用索引, A 会使用索引, 但是 B 不会使用索引, C 也不会使用索引, B,C 也不会使用索引, 这一点就不演示了