首页 > 数据库 >4.MongoDB系列之索引(一)

4.MongoDB系列之索引(一)

时间:2022-10-16 13:45:14浏览次数:78  
标签:username 系列 MongoDB db getCollection 索引 id NumberInt

1. 执行计划查看
db.getCollection('users').find({'username': 'shenjian'}).explain('executionStats')

结果查看,先大致看一遍,后续慢慢来深入理解

{
    "queryPlanner": {
        "plannerVersion": NumberInt("1"),
        "namespace": "study.users",
        "indexFilterSet": false,
        "parsedQuery": {
            "username": {
                "$eq": "shenjian"
            }
        },
        "winningPlan": {
            "stage": "COLLSCAN",
            "filter": {
                "username": {
                    "$eq": "shenjian"
                }
            },
            "direction": "forward"
        },
        "rejectedPlans": [ ]
    },
    "executionStats": {
        "executionSuccess": true,
        "nReturned": NumberInt("0"),
        "executionTimeMillis": NumberInt("518"),
        "totalKeysExamined": NumberInt("0"),
        "totalDocsExamined": NumberInt("1000000"),
        "executionStages": {
            "stage": "COLLSCAN",
            "filter": {
                "username": {
                    "$eq": "shenjian"
                }
            },
            "nReturned": NumberInt("0"),
            "executionTimeMillisEstimate": NumberInt("0"),
            "works": NumberInt("1000002"),
            "advanced": NumberInt("0"),
            "needTime": NumberInt("1000001"),
            "needYield": NumberInt("0"),
            "saveState": NumberInt("7812"),
            "restoreState": NumberInt("7812"),
            "isEOF": NumberInt("1"),
            "direction": "forward",
            "docsExamined": NumberInt("1000000")
        }
    },
    "serverInfo": {
        "host": "4a8812679047",
        "port": NumberInt("27017"),
        "version": "4.2.6",
        "gitVersion": "20364840b8f1af16917e4c23c1b5f5efd8b352f8"
    },
    "ok": 1
}
2. 创建索引
db.getCollection('users').createIndex({'username': 1})
// 查看索引
db.getCollection('users').getIndexes({})
// 删除索引
db.getCollection('users').dropIndex({'username_1'})

如果集合特别大,则新开个窗口,执行命令db.currentOp(),重点关注ns为study.users的文档,搜索msg消息查看进度

"msg": "Index Build: inserting keys from external sorter into index Index Build: inserting keys from external sorter into index: 849146/1000000 84%",
"progress": {
   "done": NumberInt("849150"),
   "total": NumberInt("1000000")
}
3. 复合索引简介
db.getCollection('users').createIndex({'age': 1, 'username': 1})

对于多条件查询,复合查询用处很大,比如上面索引会严格按照age排序在按username排序,所以按照索引键对文档排序速度会快的多

4. MONGO如何选择索引

让多个查询计划相互竞争,只有查询最优的查询计划才会被选中,mongo会维护查询计划的缓存,这样后续查询就可以直接选择索引进行查询

5. 使用复合索引原则
  • 等值过滤的键应该在最前面
  • 用于排序的键应该在多值字段之前
  • 多值过滤的键应该在最后面

这一块推荐看《MongoDB权威指南》索引章节,特别详细。如

db.getCollection('students').createIndex({'class_id': 1, 'final_grade': 1, 'student_id': 1})

索引对于查询就很高效

db.getCollection('students').find({'class_id': 54, 'student_id': {$gt: 50000}}).sort({'final_grade': 1}).explain('executionStats')
5.1 选择键的方向

基于多键排序时,方向才重要,如

db.getCollection('users').createIndex({'age': 1, 'username': -1})
5.2 使用覆盖索引

当索引中的字段包含用户请求的所有字段,呢么这个索引就覆盖了本次查询,就不会去获取实际的文档了,注意如果索引中不包含_id,则需要考虑_id不显示才能够覆盖索引查询,如

db.getCollection('users').find({'age': 110, 'username': 'user12'}, {'age': 1, 'username': 1, '_id': 0}).explain('executionStats')
{
    "queryPlanner": {
        "winningPlan": {
            // 获胜的执行计划 覆盖索引
            "stage": "PROJECTION_COVERED",
            "transformBy": {
                "age": 1,
                "username": 1,
                "_id": 0
            },
            "inputStage": {
                "stage": "IXSCAN",
                "keyPattern": {
                    "age": 1,
                    "username": 1
                },
                "indexName": "age_1_username_1"
            }
        }
    },
    "executionStats": {
        "executionSuccess": true,
        "nReturned": NumberInt("1"),
        "executionTimeMillis": NumberInt("0"),
        "totalKeysExamined": NumberInt("1"),
         // 扫描的文档数为0
        "totalDocsExamined": NumberInt("0")
    }
}
5.3 隐式索引

复核索引具有双重功能,比如也具有索引{'class_id': 1}、{'class_id': 1,'final_grade': 1}的功能

db.getCollection('students').createIndex({'class_id': 1, 'final_grade': 1, 'student_id': 1})

但是对于{'class_id': 1, 'student_id': 1}不具有隐式索引,只有使用索引前缀的查询才会收益

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

标签:username,系列,MongoDB,db,getCollection,索引,id,NumberInt
From: https://www.cnblogs.com/shenjian-online/p/16796093.html

相关文章

  • 3.MongoDB系列之查询
    1.find简介//查询所有文档db.users.find({})//查询指定条件文档db.users.find({'name':'shenjian'})//查询指定字段,1查询键0剔除键db.users.find({'name':'sh......
  • 5.MongoDB系列之索引(二)
    1.$运算符如何使用索引1.1低效的运算符$ne、$not查询可以使用索引,但不是很有效,尽量避免1.2范围查询范围查询其实是多值查询,根据复核索引规则,尽可能先等值精确匹配,然......
  • 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.问题上学的时候没有好好学,工作的时候闹了很大的一个笑话。事情是这样的,由于我们项目需要上容器云,这时候需要申请资源,其中有一项资源就是地址池,也就是你可以使用的一......