索引

说明

索引可以高效执行的查询,如果没有索引.MongoDB必须执行集合扫描,即扫描集合中的每个文档.以选择与查询语句匹配的文档.如果查询存在适当的索引,MongoDB可以使用该索引限制它必须检查的文档数.

索引是一种特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分.索引存储特定字段或字段集的值.按字段值排序.索引项的排序支持有效的相等匹配和基于范围的查询操作.此外,MongoDB还可以使用索引中的排序返回排序结果.

在创建集合的过程中,MongoDB在_id字段上创建一个唯一索引._id索引防止客户端为_id字段插入具有相同值的两个文档.

索引操作

创建索引

创建索引的语法为:db.collection.createIndex({<field>: <value>, ...},<options>).

  • 当value为1时,索引按照正序排序
  • 当value为-1时,索引按照倒叙排序
  • options为创建索引时指定的参数
    • { expireAfterSeconds: second}, 设置索引过期时间,单位秒
    • { unique: true},创建唯一索引,索引字段的值不能重复
    • { sparse: true},创建稀疏索引,把包含索引字段或字段为null的文档加入到索引中
    • 唯一索引和稀疏索引可以同时具备,即索引字段必须唯一且可以为空
    • 复合索引不具有过期时间的功能
# 为name字段创建正序索引

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

# 返回

{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1, # 创建索引前的索引数量
    "numIndexesAfter" : 2, # 创建索引后的索引数量
    "ok" : 1
}

当创建的索引为唯一索引时:索引字段缺少值的时候会设置为null,当插入的第二篇文档同样缺少索引字段的值是无法插入到集合中的.

查看索引

查看索引的语法.db.collection.getIndexes()
# 查看集合的索引

db.qvbilam.getIndexes()

# 返回
[
    { # 默认的_id索引
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_"
    },
    { # 新建的name索引
        "v" : 2,
        "key" : {
            "name" : 1 # 按照姓名生序排序
        },
        "name" : "name_1" # 索引名称
    }
]

删除索引

删除索引语法. db.collection.dropIndex('index_name')
# 删除name索引

db.qvbilam.dropIndex('name_1')

# 返回

{ "nIndexesWas" : 2, "ok" : 1 }

索引类型

# 文档数据

db.merchant.insertMany([
{ name: "Qvbilam", sex: 1, concat: {qq: 534511019, wx: "qvbilam", mobile: "135123"} },
{ name: "Eren", sex: 1, concat: {qq: 534511018, wx: "Eren", mobile: "1351234"} },
])

单健索引

MongoDB完全支持文档集合中任何字段的索引.默认情况下,所有集合都在_id字段上有一个索引.

嵌入字段创建索引

# 为concat中的qq字段创建升序索引

db.merchant.createIndex({ "concat.qq": 1 })

嵌入文档创建索引

# 为concat创建升序索引

db.merchant.createIndex({ concate: 1 })

复合索引

# 为concat创建复合索引,name与sex都是生序

db.merchant.createIndex({ name: 1, sex: 1 })

分析索引

验证索引是否被使用,db.collction.query().explain()
> db.qvbilam.find({ _id: "qvbilam_01" }).explain()
{
      ...
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN", # 阶段
                "keyPattern" : {
                    "name" : 1
                },
                "indexName" : "name_1", # 使用的索引名称
                ...
                "indexBounds" : {
                    "name" : [
                        "[\"qvbilam\", \"qvbilam\"]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
}

对联合索引字段排序只有按照创建索引时设置的排序才有效.

说明
COLLSCAN扫描全集合
IXSCAN扫描索引键中的数据
FETCH检索文件
SHARD_MERGE合并来自碎片的结果
SORT显式排序而不是使用索引顺序

嵌入文档

# 为嵌入文档创建索引
db.merchant.createIndex({ concat: 1 })

# 以下不支持索引
db.merchant.find({ "concat.qq": 534511019, "concat.wx": "qvbilam", "concat.mobile": "135123" })

联合索引

db.merchant.createIndex({ name: 1, sex: 1 })

# 当排序没有按照索引顺序排序 索引是无效的
db.merchant.find().sort({ name: 1,sex: -1 }).explain()

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "qvbilam.merchant",
        "indexFilterSet" : false,
        "parsedQuery" : {

        },
        "queryHash" : "0CC53D7A",
        "planCacheKey" : "0CC53D7A",
        "winningPlan" : {
            "stage" : "SORT",
            "sortPattern" : {
                "name" : 1,
                "sex" : -1
            },
            "memLimit" : 104857600,
            "type" : "simple",
            "inputStage" : {
                "stage" : "COLLSCAN",
                "direction" : "forward"
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "80e3cbe1e885",
        "port" : 27017,
        "version" : "4.4.0",
        "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
    },
    "ok" : 1
}
Last modification:February 25th, 2021 at 05:22 pm