`
pingfeng
  • 浏览: 59267 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

mongoDB性能初测与优化

阅读更多

测试环境:

  型号名称:    iMac
  处理器名称:    Intel Core 2 Duo
  处理器速度:    3.06 GHz
  处理器数量:    1
  总核心数:    2
  L2 高速缓存:    3 MB
  内存:    4 GB
  总线速度:    1.07 GHz

测试方案:

用js脚本创建向一个collection里插入一百万个文档,测量mongo占用内存,硬盘数据文件大小(优化数据库设计),插入时间,在一百万条基础上做find操作。

 

内存:

起动mongod之后,可用内存是2.65G. 创建完1百万条记录后,可用内存为1.34G. 说明在创建过程中审请过约1.3G内存,用完了其它程序可接着使用。

索引内存:300M,容易记的是100万个文档,3个索引字段(加系统_id),300M。

> db.process.totalIndexSize()
302638016

 

 

#导入100万个文档

db.serverStatus().mem
{
    "bits" : 64,
    "resident" : 530,
    "virtual" : 6386,
    "supported" : true,
    "mapped" : 3952
}

#未做查询
    "mem" : {
        "bits" : 64,
        "resident" : 4,
        "virtual" : 2399,
        "supported" : true,
        "mapped" : 0
    },

#做完查询
    "mem" : {
        "bits" : 64,
        "resident" : 20,
        "virtual" : 3375,
        "supported" : true,
        "mapped" : 976
    },


从以上测试来看,在生产环境下,最好预留1-2G的内存给mongod!

 

 

时间:


创建完100万个文档,时间, 3分20秒 左右(多次测试)

baicaomatoiMac:mongo baicao$ time mongo process_task.js
MongoDB shell version: 1.6.2
connecting to: test

real    3m22.432s
user    3m14.673s
sys    0m6.514s

find查询:
击中索引,基本只需要0ms(测不到),  最坏的情况也是在26ms(第一次查询),mongo在查询之后就有cach,后面基本就是0ms了。
> db.process.find({"index.task_name":"ReturnMoney","index.user_id":100,"index.status":1}).explain()
{
    "cursor" : "BtreeCursor index.task_name_1_index.user_id_1_index.status_1",
    "nscanned" : 50,
    "nscannedObjects" : 50,
    "n" : 50,
    "millis" : 0,
    "indexBounds" : {
        "index.task_name" : [
            [
                "ReturnMoney",
                "ReturnMoney"
            ]
        ],
        "index.user_id" : [
            [
                100,
                100
            ]
        ],
        "index.status" : [
            [
                1,
                1
            ]
        ]
    }
}

不是完全击中索引,加上process_id(非索引字段)这个查询条件,速度也是非常快,基本只要1ms, 最差在8ms(第一次)。即先用索引击中100或200条记录,再在这百条记录里查找process_id,也是非常快。

 

这给我们一个启示,只对最关键的字段做索引。有些字段可以让mongo去遍历的。 如果都做成索引,那索引太大,需要的内存就要非常大!


> db.process.find({"index.task_name":"Precontract","index.user_id":100,"index.status":1, process_id:0}).explain()
{
    "cursor" : "BtreeCursor index.task_name_1_index.user_id_1_index.status_1",
    "nscanned" : 100,
    "nscannedObjects" : 100,
    "n" : 100,
    "millis" : 1,
    "indexBounds" : {
        "index.task_name" : [
            [
                "Precontract",
                "Precontract"
            ]
        ],
        "index.user_id" : [
            [
                100,
                100
            ]
        ],
        "index.status" : [
            [
                1,
                1
            ]
        ]
    }
}

如果没有索引,一百万条记录,对4个字段查找(遍历),要1000ms左右。
速度还是非常快,但离可用性还是有距离。

 

缩小数据库文件大小

 

MongoDB查询能力强,性能好,但代价是内存开销大,数据库文件大。每个文档都有字段定义!

 

用第一个脚本创建:process_task.js(见附件)创建,100万条文档需要2G-3G大小的数据库文件。

 

文件大小: 128 + 256 + 512 + 1024 + 1024 * 2  = 3968 M, 约4G, 最后的2G可能没怎么用,那最小也在2G左右
-rw-------  1 root  admin   134217728  4  1 10:28 genius_t_1.1
-rw-------  1 root  admin   268435456  4  1 10:28 genius_t_1.2
-rw-------  1 root  admin   536870912  4  1 10:28 genius_t_1.3
-rw-------  1 root  admin  1073741824  4  1 10:28 genius_t_1.4
-rw-------  1 root  admin  2146435072  4  1 10:27 genius_t_1.5

用mongo自带命令查看

 

genius_t_1:  663M, 每个文档平均大小是544!

> db.printCollectionStats()
process
{
    "ns" : "genius_t_1.process",
    "count" : 1000000,
    "size" : 544000000,
    "avgObjSize" : 544,
    "storageSize" : 663950336,
    "numExtents" : 20,
    "nindexes" : 2,
    "lastExtentSize" : 117793792,
    "paddingFactor" : 1,
    "flags" : 1,
    "totalIndexSize" : 302638016,
    "indexSizes" : {
        "_id_" : 41394176,
        "index.task_name_1_index.user_id_1_index.status_1" : 261243840
    },
    "ok" : 1
}

用process_task_short.js创建,把process_id 简写为pid, user_id, 简写为uid, task_name, 简写为name

 

genius_t_2: 616M, 每个文档平均大小是508!

process
{
    "ns" : "genius_t_2.process",
    "count" : 1000000,
    "size" : 508000000,
    "avgObjSize" : 508,
    "storageSize" : 616527872,
    "numExtents" : 20,
    "nindexes" : 2,
    "lastExtentSize" : 109380352,
    "paddingFactor" : 1,
    "flags" : 1,
    "totalIndexSize" : 302638016,
    "indexSizes" : {
        "_id_" : 41394176,
        "index.name_1_index.uid_1_index.state_1" : 261243840
    },
    "ok" : 1
}

用process_task_short_short.js创建,把手机号用整数方式来存,再一步缩短字段名。

 

genius_t_3 : 499M, 每个文档平均大小是460, 比最初的544,下降了15%的空间 。数据库文件上也没有出来2G的那个文件了。所以,这种优化还是非常值的,就是可读性略有下降。但只对约定的字段进行简缩,并没有对任务名进行缩简。

process
{
    "ns" : "genius_t_3.process",
    "count" : 1000000,
    "size" : 460000136,
    "avgObjSize" : 460.000136,
    "storageSize" : 499348736,
    "numExtents" : 19,
    "nindexes" : 2,
    "lastExtentSize" : 89748992,
    "paddingFactor" : 1,
    "flags" : 1,
    "totalIndexSize" : 284779456,
    "indexSizes" : {
        "_id_" : 41394176,
        "index.name_1_index.uid_1_index.mob_1" : 243385280
    },
    "ok" : 1
}

总结:

 

1.  mongoDB占用内存挺大的,虚拟内存都是1G以上,随着查询,会用更多的内存(索引)被进驻,生产环境最好留1-2G给mongoDB

 

2. mongoDB的性能非常好,在有索引的情况下,0ms。没有必要所有的字段都做成索引,先用索引确定几百个文档,对非索引字段进行遍历,也只需要1ms。

 

3. mongoDB的数据库文件也非常大,100万条文档也有在1G以上。所以数据库设计时,在保证可读性性的前提下,尽量缩短字段名 。像常用的字段(约定俗成)长度最好在5个字符以下。参考测试附件。

 

附件:

 

测试脚本:

分享到:
评论
3 楼 grandboy 2011-04-18  
seekboy 写道
内存如果不够大,没有装入所有索引,效率上相差还是挺多的


内存不够的情况,效率差到什么程度? 和mysql的比较有多大差别? 当然首先得知道是否能正常运行?
2 楼 seekboy 2011-04-18  
内存如果不够大,没有装入所有索引,效率上相差还是挺多的
1 楼 grandboy 2011-04-17  
我一直担心的就是内存问题,好像没有办法限制内存大小,据说要求内存足够装下所有数据才行,这点我还没有测试过,不知道超过只会导致性能损失,还是内存溢出的异常呢。

相关推荐

    万亿级文档数据库MongoDB集群性能优化实践.pdf

    "MongoDB集群性能优化实践" 本文档主要介绍了MongoDB集群性能优化实践,涵盖了从 MongoDB 集群优化到解决方案的分享。通过本文档,我们可以了解到 MongoDB 集群性能优化的重要性,并学习到实际的解决方案。 知识点...

    MongoDB进阶与实战:微服务整合、性能优化、架构管理.docx

    MongoDB 进阶与实战:微服务整合、性能优化、架构管理 MongoDB 是一种流行的开源非关系型数据库(NoSQL),它以文档为模型,使用类似于 JSON 的 BSON 格式进行数据存储。MongoDB 具有强大的查询和索引功能,并且...

    mongodb性能优化.pptx

    ### MongoDB性能优化详解 #### 一、MongoDB性能优化概述 MongoDB作为一种广泛使用的NoSQL数据库,因其灵活性和高扩展性而备受青睐。然而,在实际应用过程中,由于数据量的增长和查询复杂性的增加,可能会遇到性能...

    mysql和mongodb性能对比报告

    ### MySQL与MongoDB性能对比分析 #### 测试背景与目的 随着大数据时代的到来,数据库的选择对系统的性能至关重要。本报告旨在通过一系列实验对比MySQL和MongoDB两种不同类型的数据库(关系型数据库与NoSQL数据库)...

    MongoDB性能调优(基于MMS)

    在基于MongoDB的Ops Manager(MMS)上进行性能调优,能够让用户通过一系列监控指标分析出MongoDB性能问题的根本原因,并据此进行相应的优化。 在进行性能调优时,我们首先需要定义用于指导性能调查的关键指标,随后...

    MongoDB查询性能验证及优化

    本文将深入探讨如何验证MongoDB查询性能并进行优化。 首先,我们需要理解MongoDB的查询机制。MongoDB使用查询解释器来解析和执行查询操作。通过`explain()`方法,我们可以获取查询的执行计划,包括扫描的文档数量、...

    MongoDB性能测试报告

    这些信息对于数据库管理员和开发者来说是宝贵的,他们可以根据这些数据来优化数据库的配置和性能,从而满足应用程序对数据库性能的高要求。报告最后总结了插入和查询的性能表现,并提出了一些未解决的问题,这些问题...

    万亿级文档数据库MongoDB集群性能优化实践.pptx

    MongoDB 集群性能优化实践 MongoDB 集群性能优化实践 MongoDB 作为一个 NoSQL 数据库,越来越多地应用于大规模数据存储和处理中。然而,随着数据规模的增长,MongoDB 集群的性能优化也变得越来越重要。本文将...

    MongoDB疑难杂症分析及优化

    MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化...

    MongoDB性能调优

    MongoDB 有一个数据库优化工具 Database Profiler,这个工具能检测数据库操作的性能。使用这个工具可以发现 query 或者 write 操作中执行效率低的,从而针对这些操作进行优化。 优化 count() 查询操作 在 count() ...

    千万级Mysql-MongoDB性能对比报告

    然而,在处理小规模数据时,MongoDB与MySQL的表现相近或略差。此外,MongoDB在大规模数据插入时对系统资源(尤其是内存)的消耗更为显著。 针对这些发现,建议在实际应用中根据数据特性和应用场景选择合适的数据库...

    MongoDB 性能最佳实践

    在使用 MongoDB 构建高性能应用时,了解并实践性能优化策略至关重要。本篇文章将深入探讨 MongoDB 的性能最佳实践,旨在帮助你充分利用其潜力。 1. **数据模型设计** - **合适的文档结构**:设计紧凑且逻辑清晰的...

    MongoDB性能优化

    然而,随着数据量的增长,性能优化成为确保MongoDB高效运行的关键环节。本篇文章将深入探讨MongoDB性能优化的相关知识点,帮助你提升数据库的运行效率。 一、索引优化 1. 创建合适索引:索引是提高查询速度的关键。...

    MongoDB数据库性能优化

    MongoDB数据库性能优化,包括内存优化、存储优化、配置优化

    MongoDB北京2014 - MongoDB性能扩展 - 唐建法

    通过上述案例和策略的介绍,我们可以看到,MongoDB性能扩展是一个多方面的过程,涉及数据模型设计、索引选择、内存和I/O优化等多个方面。只有综合考虑这些因素,并根据具体的业务场景进行灵活调整,才能最大限度地...

    MongoDB数据压缩与优化:释放NoSQL数据库的性能潜力

    MongoDB是一个基于文档的NoSQL数据库,它以其高性能、高可用性和易扩展性而闻名。MongoDB数据库存储BSON(二进制JSON)格式的数据记录,这使得它在存储复杂数据结构方面非常灵活。以下是MongoDB的一些关键特性: 1....

    MongoDB数据库应用与优化进阶.pptx

    在本篇关于“MongoDB数据库应用与优化进阶”的内容中,我们将深入探讨MongoDB的一些核心特性、部署架构以及最佳实践,以帮助你更好地理解和优化MongoDB在实际应用中的性能。 首先,MongoDB的核心特性之一是它的文档...

Global site tag (gtag.js) - Google Analytics