MongoDB存储引擎、索引

wiredTigerlinux

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

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

 

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

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

 

写策略解析服务器

配置文件并发

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 > noneapp

 

索引命令概要与类型函数

索引一般可以极大的提升查询的效率,若是没有索引,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为索引的属性,属性说明见下表;

建立索引
 单键惟一索引: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)

查询优化技巧 第二步

分析慢速查询

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

使用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. 索引是用来查询小范围数据的,不适合使用索引的状况:      每次查询都须要返回大部分数据的文档,避免使用索引      写比读多

相关文章
相关标签/搜索