MongoDB存储引擎、索引 原

Wesley13
• 阅读 456

wiredTiger

       MongoDB从3.0开始引入可插拔存储引擎的概念。目前主要有MMAPV1、WiredTiger存储引擎可供选择。在3.2版本之前MMAPV1是默认的存储引擎,其采用linux操作系统内存映射技术,但一直饱受诟病;3.4以上版本默认的存储引擎是wiredTiger,相对于MMAPV1其有如下优势:

 读写操作性能更好,WiredTiger能更好的发挥多核系统的处理能力;
 MMAPV1引擎使用表级锁,当某个单表上有并发的操作,吞吐将受到限制。WiredTiger使用文档级锁,由此带来并发及吞吐的提高
 相比MMAPV1存储索引时WiredTiger使用前缀压缩,更节省对内存空间的损耗;
 提供压缩算法,可以大大降低对硬盘资源的消耗,节省约60%以上的硬盘资源;

mongodb数据会丢失?你需要了解WT写入的原理

MongoDB存储引擎、索引 原

Journaling类似于关系数据库中的事务日志。Journaling能够使MongoDB数据库由于意外故障后快速恢复。MongoDB2.4版本后默认开启了Journaling日志功能,mongod实例每次启动时都会检查journal日志文件看是否需要恢复。由于提交journal日志会产生写入阻塞,所以它对写入的操作有性能影响,但对于读没有影响。在生产环境中开启Journaling是很有必要的。

写策略解析MongoDB存储引擎、索引 原

配置文件

storage:
    journal:
        enabled: true
    dbPath: /data/zhou/mongo1/
    ##是否一个库一个文件夹
    directoryPerDB: true
    ##数据引擎
    engine: wiredTiger
    ##WT引擎配置
    WiredTiger:
        engineConfig:
            ##WT最大使用cache(根据服务器实际情况调节)
            cacheSizeGB: 1
            ##是否将索引也按数据库名单独存储
            directoryForIndexes: true
            journalCompressor:none (默认snappy)
        ##表压缩配置
        collectionConfig:
            blockCompressor: zlib (默认snappy,还可选none、zlib)
        ##索引配置
        indexConfig:
            prefixCompression: true

压缩 算法 Tips:
性能: none > snappy >zlib
压缩比:zlib > snappy > none

索引命令概要与类型

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。索引主要用于排序和检索

单键索引

在某一个特定的属性上建立索引,例如:db.users. createIndex({age:-1});
 mongoDB在ID上建立了唯一的单键索引,所以经常会使用id来进行查询;
 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引;

复合索引

在多个特定的属性上建立索引,例如:db.users. createIndex({username:1,age:-1,country:1});
 复合索引键的排序顺序,可以确定该索引是否可以支持排序操作;
 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引,但与索引的顺序有关;
 为了性能考虑,应删除存在与第一个键相同的单键索引

多键索引

在数组的属性上建立索引,例如:db.users. createIndex({favorites.city:1});针对这个数组的任意值
的查询都会定位到这个文档,既多个索引入口或者键值引用同一个文档

哈希索引

不同于传统的B-树索引,哈希索引使用hash函数来创建索引。
例如:db.users. createIndex({username : 'hashed'});
 在索引字段上进行精确匹配,但不支持范围查询,不支持多键hash;
 Hash索引上的入口是均匀分布的,在分片集合中非常有用;

索引语法

 MongoDB使用 ensureIndex() 方法来创建索引,ensureIndex()方法基本语法格式如下所示:

        db.collection.createIndex(keys, options)

 语法中 Key 值为要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1,也可以指定为hashed(哈希索引)。
 语法中options为索引的属性,属性说明见下表;

MongoDB存储引擎、索引 原

创建索引
 单键唯一索引:db.users. createIndex({username :1},{unique:true});
 单键唯一稀疏索引:db.users. createIndex({username :1},{unique:true,sparse:true});
 复合唯一稀疏索引:db.users. createIndex({username:1,age:-1},{unique:true,sparse:true});
 创建哈希索引并后台运行:db.users. createIndex({username :'hashed'},{background:true});
删除索引
 根据索引名字删除某一个指定索引:db.users.dropIndex("username_1");
 删除某集合上所有索引:db.users.dropIndexs();
 重建某集合上所有索引:db.users.reIndex();
 查询集合上所有索引:db.users.getIndexes();

查询优化技巧 第一步

找出慢速查询

开启内置的查询分析器,记录读写操作效率:
    db.setProfilingLevel(n,{m}),n的取值可选0,1,2;
         0是默认值表示不记录;
         1表示记录慢速操作,如果值为1,m必须赋值单位为ms,用于定义慢速查询时间的阈值;
         2表示记录所有的读写操作;
    例如:db.setProfilingLevel(1,300)

查询监控结果

       监控结果保存在一个特殊的盖子集合system.profile里,这个集合分配了128kb的空间,要确保监控分析数据不会消耗太多的系统性资源;盖子集合维护了自然的插入顺序,可以使用$natural操作符进行排序,如:db.system.profile.find().sort({'$natural':-1}).limit(5)

MongoDB存储引擎、索引 原

查询优化技巧 第二步

分析慢速查询

找出慢速查询的原因比较棘手,原因可能有多个:应用程序设计不合理、不正确的数据模型、硬件配置问题,缺少索引等;接下来对于缺少索引的情况进行分析:

使用explain分析慢速查询

    例如:db.orders.find({'price':{'$lt':2000}}).explain('executionStats')

    explain的入参可选值为:

     "queryPlanner" 是默认值,表示仅仅展示执行计划信息;
     "executionStats" 表示展示执行计划信息同时展示被选中的执行计划的执行情况信息;
      "allPlansExecution" 表示展示执行计划信息,并展示被选中的执行计划的执行情况信息,还展示备选的执行计划的执行情况信息;

查询优化技巧 第三步

解读explain结果

    queryPlanner(执行计划描述)
            winningPlan(被选中的执行计划)
                    stage(可选项:COLLSCAN 没有走索引;IXSCAN使用了索引)
            rejectedPlans(候选的执行计划)
    executionStats(执行情况描述)
            nReturned (返回的文档个数)
            executionTimeMillis(执行时间ms)
            totalKeysExamined (检查的索引键值个数)
            totalDocsExamined (检查的文档个数)

优化目标 Tips:
1. 根据需求建立索引
2. 每个查询都要使用索引以提高查询效率, winningPlan. stage 必须为IXSCAN ;
3. 追求totalDocsExamined = nReturned

关于索引的建议

1. 索引很有用,但是它也是有成本的——它占内存,让写入变慢;
2. mongoDB通常在一次查询里使用一个索引,所以多个字段的查询或者排序需要复合索引才能更加高效;
3. 复合索引的顺序非常重要
4. 在生成环境构建索引往往开销很大,时间也不可以接受,在数据量庞大之前尽量进行查询优化和构建索引;
5. 避免昂贵的查询,使用查询分析器记录那些开销很大的查询便于问题排查;
6. 通过减少扫描文档数量来优化查询,使用explai对开销大的查询进行分析并优化;
7. 索引是用来查询小范围数据的,不适合使用索引的情况:
     每次查询都需要返回大部分数据的文档,避免使用索引
     写比读多

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
MongoDB journal 与 oplog,究竟谁先写入?
MongoDBjournal与oplog,谁先写入?最近经常被人问到,本文主要科普一下MongoDB里oplog以及journal这两个概念。journaljournal是MongoDB存储引擎层的概念,目前MongoDB主要支持mmapv1、wiredtiger、mongorocks等存储引擎,都支持配
Wesley13 Wesley13
2年前
MongoDB 存储引擎说明
MongoDB存储引擎说明MongoDB存储引擎可以插件化(3.0开始提供插件化API),根据不同的场景选择不同的存储引擎,跟Mysql有点类似。MongoDB常用存储引擎:WiredTiger,MMAPv1,InMemoryMongoDB存储引擎之WiredTiger3.2版本开始WiredTiger已经是M
Wesley13 Wesley13
2年前
MySQL数据库表设计规范
一、数据库设计1、一般都使用INNODB存储引擎,除非读写比率<1%,才考虑使用MYISAM存储引擎;其他存储引擎请在DBA的建议下使用。2、Storedprocedure(包括存储过程,函数,触发器)对于MYSQL来说还不是很成熟,没有完善的出错记录处理,不建议使用。3、UUID(),USER()这样的
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
MongoDB(引擎)关于存储引擎 WiredTiger storage engine
WiredTiger(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Flink.jianshu.com%3Ft%3Dhttp%3A%2F%2Fwww.wiredtiger.com%2F)在3.2版本成为mongodb的默认存储引擎。所以这里讲的就是WiredTiger了。Doc
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这