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 也不会使用索引, 这一点就不演示了

posted @   BNTang  阅读(340)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示