测试环境:
型号名称: 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个字符以下。参考测试附件。
附件:
测试脚本:
分享到:
相关推荐
"MongoDB集群性能优化实践" 本文档主要介绍了MongoDB集群性能优化实践,涵盖了从 MongoDB 集群优化到解决方案的分享。通过本文档,我们可以了解到 MongoDB 集群性能优化的重要性,并学习到实际的解决方案。 知识点...
MongoDB 进阶与实战:微服务整合、性能优化、架构管理 MongoDB 是一种流行的开源非关系型数据库(NoSQL),它以文档为模型,使用类似于 JSON 的 BSON 格式进行数据存储。MongoDB 具有强大的查询和索引功能,并且...
### MongoDB性能优化详解 #### 一、MongoDB性能优化概述 MongoDB作为一种广泛使用的NoSQL数据库,因其灵活性和高扩展性而备受青睐。然而,在实际应用过程中,由于数据量的增长和查询复杂性的增加,可能会遇到性能...
### MySQL与MongoDB性能对比分析 #### 测试背景与目的 随着大数据时代的到来,数据库的选择对系统的性能至关重要。本报告旨在通过一系列实验对比MySQL和MongoDB两种不同类型的数据库(关系型数据库与NoSQL数据库)...
在基于MongoDB的Ops Manager(MMS)上进行性能调优,能够让用户通过一系列监控指标分析出MongoDB性能问题的根本原因,并据此进行相应的优化。 在进行性能调优时,我们首先需要定义用于指导性能调查的关键指标,随后...
本文将深入探讨如何验证MongoDB查询性能并进行优化。 首先,我们需要理解MongoDB的查询机制。MongoDB使用查询解释器来解析和执行查询操作。通过`explain()`方法,我们可以获取查询的执行计划,包括扫描的文档数量、...
这些信息对于数据库管理员和开发者来说是宝贵的,他们可以根据这些数据来优化数据库的配置和性能,从而满足应用程序对数据库性能的高要求。报告最后总结了插入和查询的性能表现,并提出了一些未解决的问题,这些问题...
MongoDB 集群性能优化实践 MongoDB 集群性能优化实践 MongoDB 作为一个 NoSQL 数据库,越来越多地应用于大规模数据存储和处理中。然而,随着数据规模的增长,MongoDB 集群的性能优化也变得越来越重要。本文将...
MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化...
MongoDB 有一个数据库优化工具 Database Profiler,这个工具能检测数据库操作的性能。使用这个工具可以发现 query 或者 write 操作中执行效率低的,从而针对这些操作进行优化。 优化 count() 查询操作 在 count() ...
然而,在处理小规模数据时,MongoDB与MySQL的表现相近或略差。此外,MongoDB在大规模数据插入时对系统资源(尤其是内存)的消耗更为显著。 针对这些发现,建议在实际应用中根据数据特性和应用场景选择合适的数据库...
在使用 MongoDB 构建高性能应用时,了解并实践性能优化策略至关重要。本篇文章将深入探讨 MongoDB 的性能最佳实践,旨在帮助你充分利用其潜力。 1. **数据模型设计** - **合适的文档结构**:设计紧凑且逻辑清晰的...
然而,随着数据量的增长,性能优化成为确保MongoDB高效运行的关键环节。本篇文章将深入探讨MongoDB性能优化的相关知识点,帮助你提升数据库的运行效率。 一、索引优化 1. 创建合适索引:索引是提高查询速度的关键。...
MongoDB数据库性能优化,包括内存优化、存储优化、配置优化
通过上述案例和策略的介绍,我们可以看到,MongoDB性能扩展是一个多方面的过程,涉及数据模型设计、索引选择、内存和I/O优化等多个方面。只有综合考虑这些因素,并根据具体的业务场景进行灵活调整,才能最大限度地...
MongoDB是一个基于文档的NoSQL数据库,它以其高性能、高可用性和易扩展性而闻名。MongoDB数据库存储BSON(二进制JSON)格式的数据记录,这使得它在存储复杂数据结构方面非常灵活。以下是MongoDB的一些关键特性: 1....
在本篇关于“MongoDB数据库应用与优化进阶”的内容中,我们将深入探讨MongoDB的一些核心特性、部署架构以及最佳实践,以帮助你更好地理解和优化MongoDB在实际应用中的性能。 首先,MongoDB的核心特性之一是它的文档...