学海无涯 个人blog lnmps.com 新站
分类: LINUX
2013-10-05 20:22:27
建立索引是优化数据库最直接的手段.遵循以下索引优化原则,可以建立比较高效和合理的索引.
在索引中包含条件的所有列,可以使用索引形成的屏蔽来拒绝结果集中不合适的行
对于需要排序的引用列,适当地创建索引可以避免排序
考虑到管理上的开销,应避免在索引中使用多于5个的列
对于多列索引,将查询中引用最多的列放在定义的前面
不要在索引中包含经常修改或进行插入、删除的列(主关键字和外来关键字除外)
“$”符号不可以作为索引的首字母,”.”不能在索引名的任何位置出现.
索引管理
1.建立索引的函数:ensureIndex();
eg.在name上建立索引1(升序),-1(降序),默认为升序.
db.person.ensureIndex( { name : 1 } );
当系统已有大量数据时,创建索引非常耗时,需要在后头执行,只需要指定background:true即可.
db.user.ensureIndex( { age : 1 } , { background : true } );
建立索引后,同一条查询语句比较2次扫描的记录条数. > db.user.find( { name:"user5" } ).explain();
2.获取集合中的索引信息
db.person.getIndexKeys();
db.person.getIndexes();
3.创建唯一索引
只需要在ensureIndex命令中指定"unique:true"即可创建唯一索引
db.user.ensureIndex( {age:1} , {unique:true} );
创建了唯一索引的字段不允许插入相同的值.
4.创建组合索引
db.user.ensureIndex({“addr.city”:1 , “addr.state”:1}); //在user集合的addr.city和addr.state列上创建组合索引.
5.删除索引
db.user.dropIndexes(); //删除usre表中的除过id外的所有索引 db.user.dropIndex( {age:1} ); //删除user表中的age索引
性能优化
explain 查看执行计划
MongoDB提供了一个explain命令让我们获知系统如何处理查询请求,利用explain命令我们可以很好地观察系统
如何使用索引来加快检索,同时可以针对性优化索引.
优化器profile
MongoDB Database Profiler是一种慢查询日志功能,可以作为我们优化数据库的依据.
开启Profiling功能,有2种方式可以控制Profiling的开关盒级别。
启动MonggoDB时加上-profile=级别即可
在客户端调用db.setProfilingLevel(级别)命令来实时配置。
Profiler信息保存在system.profile中.我们可以通过db.getProfilingLevel()命令来获取当前的Profile级别.
profile的级别有3个,分别是0、1、2.默认没有开启
0 - 表示不开启 1 - 表示记录慢命令(默认为>100ms) 2 - 表示记录所有命令
profile在级别1时会记录慢命令,默认值为100ms,设置慢记录的方法有2个
1.通过slowms启动参数配置 2.db.setProfilingLevel(1,设置ms参数)时加上第二个参数.
性能监控
通过对数据库的性能监控,能够更好的了解数据库的工作状态,从而进行优化.
几个性能监控的工具:
1.mongosniff
此功能可以从底层监控到底有哪些命令发送给mongoDB去执行,
./mongosniff --source net lo
它是实时动态监视的,需要打开另一个客户端进行命令操作.可以讲这些数据输出到一个日志文件中,
那么就可以保留下所有数据库操作的历史记录,对于后期的性能分析和安全审计等工作将是一个巨大的贡献.
“lo”即Loopback,指IP数据包会送到本机上,通常使用的是127.0.0.1作为回送地址,Loopback通常用于检测网络配置和本地程序之间通信.
2.mongostat
此工具可以快速的查看某组运行中的MongoDB实例的统计信息,也需要在打开另一个客户端进行命令操作
./mongostat
3.db.serverStatus命令
该命令可以查看服务器运行状态,是最基础的查看实例运行状态的命令
4.db.stats命令
MongoDB不但可以查看实例级运行状态信息,而且可以通过运行”db.stats”命令查看特定数据库的详细运行状态,更细粒度地分析故障.
优化方案
优化方案1:创建索引
在查询条件的字段上,或者排序条件的字段上创建索引,可以显著提高执行效率.
db.user.ensureIndex( { name:1 } );
优化方案2 : 限定返回结果条数
使用limit()限定返回结果集的大小,可以减少database server的资源消耗,可以减少网络传输数据量.
db.user.find().sort( {age:-1} ).limit(5);
优化方案3:查询使用到的字段,不查询所有字段
db.user.find( {} , {name:1} ).sort( { age:-1} ).limit(5) ;
优化方案4:采用capped collection
capped Collections比普通Collections的读写效率高
优化方案5:采用Profiling
Profiling功能肯定是会影响效率的,但是不太严重,原因是他使用的是system.profile来记录,system.profile是一个capped collection 这种collection在操作上有一些限制和特点,但是效率更高.