首页 > 数据库 >5.MongoDB系列之索引(二)

5.MongoDB系列之索引(二)

时间:2022-10-16 13:44:05浏览次数:77  
标签:username 系列 MongoDB age 查询 索引 8321 NumberInt

1. $运算符如何使用索引
1.1 低效的运算符

$ne、$not查询可以使用索引,但不是很有效,尽量避免

1.2 范围查询

范围查询其实是多值查询,根据复核索引规则,尽可能先等值精确匹配,然后范围查询

1.3 OR查询

$or实际执行两个索引查询然后合并,应尽可能使用$in,而非$or

2. 索引对象和数组
2.1 索引内嵌文档
db.getCollection('users').createIndex({'loc.city': 1})
2.2 索引数组
db.getCollection('blog').createIndex({'comments.date': 1})

对数组索引就是对数组的每个元素创建索引项,代价比较高,尽量避免使用

2.3 多键索引

如果一个文档有被索引的数组字段,则该索引被标记为多键索引,恢复非多键索引只能删除索引重建

2.4 索引基数

基数是指集合中某个字段有多少个不通的值。根据经验来讲,应该把基数比较高的键放在复核索引的前面,比如对username在前,gender在后

3. explain输出详解
db.getCollection('users').find({'age': 42}).explain('executionStats')
{
    "queryPlanner": {
        "plannerVersion": NumberInt("1"),
        // 集合名称
        "namespace": "study.users",
        "indexFilterSet": false,
        "parsedQuery": {
            "age": {
                "$eq": 42
            }
        },
        // 获胜执行计划
        "winningPlan": {
            "stage": "FETCH",
            "inputStage": {
                "stage": "IXSCAN",
                "keyPattern": {
                    "age": 1,
                    "username": 1
                },
                // 索引名称
                "indexName": "age_1_username_1",
                // 是否使用多键索引
                "isMultiKey": false,
                "multiKeyPaths": {
                    "age": [ ],
                    "username": [ ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "age": [
                        "[42.0, 42.0]"
                    ],
                    "username": [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans": [ ]
    },
    "executionStats": {
        "executionSuccess": true,
        // 实际返回的文档数
        "nReturned": NumberInt("8321"),
        // 查询计划花费的总运行时间
        "executionTimeMillis": NumberInt("465"),
        // 扫描的索引项数量
        "totalKeysExamined": NumberInt("8321"),
        // 扫描的文档数
        "totalDocsExamined": NumberInt("8321"),
        "executionStages": {
            "stage": "FETCH",
            "nReturned": NumberInt("8321"),
            "executionTimeMillisEstimate": NumberInt("207"),
            "works": NumberInt("8322"),
            "advanced": NumberInt("8321"),
            "needTime": NumberInt("0"),
            "needYield": NumberInt("0"),
            "saveState": NumberInt("65"),
            "restoreState": NumberInt("65"),
            "isEOF": NumberInt("1"),
            "docsExamined": NumberInt("8321"),
            "alreadyHasObj": NumberInt("0"),
            "inputStage": {
                // IXSCAN使用索引执行查询,如果是COLLSCAN表示集合扫描进行查询
                "stage": "IXSCAN",
                "nReturned": NumberInt("8321"),
                "executionTimeMillisEstimate": NumberInt("0"),
                "works": NumberInt("8322"),
                "advanced": NumberInt("8321"),
                "needTime": NumberInt("0"),
                 // 为了让写请求顺利执行,本次查询让步(暂停)的次数
                "needYield": NumberInt("0"),
                "saveState": NumberInt("65"),
                "restoreState": NumberInt("65"),
                "isEOF": NumberInt("1"),
                "keyPattern": {
                    "age": 1,
                    "username": 1
                },
                "indexName": "age_1_username_1",
                "isMultiKey": false,
                "multiKeyPaths": {
                    "age": [ ],
                    "username": [ ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                // 索引是如何被使用的,给出索引遍历范围
                "indexBounds": {
                    "age": [
                        "[42.0, 42.0]"
                    ],
                    "username": [
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined": NumberInt("8321"),
                "seeks": NumberInt("1"),
                "dupsTested": NumberInt("0"),
                "dupsDropped": NumberInt("0")
            }
        }
    },
    "serverInfo": {
        "host": "4a8812679047",
        "port": NumberInt("27017"),
        "version": "4.2.6",
        "gitVersion": "20364840b8f1af16917e4c23c1b5f5efd8b352f8"
    },
    "ok": 1
}
4. 何时不使用索引

索引在提交较小子数据集时最高效,当结果集在原集合所占百分比大, 则低效,因为使用索引需要两个查询:一次是查询索引项,在根据索引指针查询指向的文档,而全表查询只需要一次查询:查找文档

5. 索引类型
5.1 唯一索引

唯一索引确保每个值在索引中只会出现一次。如果保证不同文档的'firstname'键拥有不通的值,则可如下

db.getCollection('users').createIndex({'firstname': 1}, {'unique': true, 'partialFilterExpression': {'firstname': {$exists: true}}})

当重复键出现时会出现

db.getCollection('users').insert({'firstname': 'shen'})
> [Error] index 0: 11000 - E11000 duplicate key error collection: study.users index: firstname_1 dup key: { firstname: \"shen\" }
> 时间: 0.022s
5.2 部分索引

部分索引不是唯一的,要创建部分索引,将唯一索引{unique: true}去掉即可

欢迎关注公众号算法小生沈健的技术博客

标签:username,系列,MongoDB,age,查询,索引,8321,NumberInt
From: https://www.cnblogs.com/shenjian-online/p/16796094.html

相关文章

  • mongodb基础整理篇————副本概念篇[外篇]
    前言副本集整理。开始逐步把mongodb博客补齐了。正文什么是副本集副本集是一组服务器,其中一个是用于处理写入操作的主节点,还有多个用于保存主节点的数据副本的从节点......
  • MongoDB笔记
    MongoDB笔记非关系型数据库中的文档数据库本质就是存各种各样的JSON(数据库(集合(文档)))(数据库(集合(文档)))安装使用步骤:--下载安装--将bin文件目录添加到path路径--在C盘根......
  • Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
    参考书籍《mysql是怎样运行的》非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容书中还讲解了本文没有提到的子查询优化内容,本文只总结了常见的子查询是如何优化的系......
  • 索引基本操作
    索引格式PUT/my_index{ ##settings用来设置分片,副本等信息"settings":{...anysettings...},##字段映射,类型,分词器等 "mappings":{"p......
  • 数据库基础 ——索引及优化
    一、关系型数据库的大致架构  关系型数据库大致分为两个部分:  1.DB:数据库(Database),即存储数据的仓库,其本质是一个文件系统,保存一系列有组织的数据。  2.DBMS:数据......
  • 详解降维-主成分分析-概率角度(Probabilistic PCA)【白板推导系列笔记】
    教科书对PCA的推导一般是基于最小化重建误差或者最大化可分性的,或者说是通过提取数据集的结构信息来建模一个约束最优化问题来推导的。事实上,PCA还有一种概率形式的推导,那......
  • 详解支持向量机-硬间隔SVM-模型定义【白板推导系列笔记】
    支撑向量机(SVM)算法在分类问题中有着重要地位,其主要思想是最大化两类之间的间隔。按照数据集的特点:1. 线性可分问题,如之前的感知机算法处理的问题2. 线性可分,只有一点......
  • 常见的问题系列--【什么是子网掩码?】
    1.问题上学的时候没有好好学,工作的时候闹了很大的一个笑话。事情是这样的,由于我们项目需要上容器云,这时候需要申请资源,其中有一项资源就是地址池,也就是你可以使用的一......
  • 【第四篇】Camunda系列-ProcessEngine核心对象
    一、ProcessEngine  ProcessEngine是Camunda流程引擎的核心。我们在流程中的很多具体的处理比如​​流程部署​​​、​​流程部署​​​、​​流程审批​​​等操作都是......
  • 【第五篇】Camunda系列-任务分配
    任务分配1.固定分配  在指派​​用户任务​​的审批人时。我们是直接指派的固定账号。但是为了保证流程设计审批的灵活性。我们需要各种不同的分配方式,所以这节我们就详细......