mongodb索引的优化
mongodb索引的优化
mongodb索引的优化一、索引简介
例如如下数据
db.refactor.insert({"username":"refactor","age":24,"isactive":true})
db.refactor.insert({"username":"refactor","age":30,"isactive":false})
db.refactor.insert({"username":"aaaaa","age":24,"isactive":false})
db.refactor.insert({"username":"aaaaa","age":34,"isactive":true})
db.refactor.insert({"username":"sssssss","age":24,"isactive":true})
db.refactor.insert({"username":"tttttt","age":24,"isactive":true})
db.refactor.insert({"username":"tttttt","age":54,"isactive":true})
db.refactor.insert({"username":"bbbbb","age":24,"isactive":false})
db.refactor.insert({"username":"rrrrr","age":24,"isactive":true})
db.refactor.insert({"username":"rrrrr","age":54,"isactive":false})
MongoDB提供了一个explain命令让我们获知系统如何处理查询请求。利用explain命令,我们可以很好地观察系统如何使用索引来加快检索同时可以针对性优化索引。
几个关键的字段说明
cursor:返回游标类型(BasicCursor或BtreeCursor)
nscanned:被扫描的文档数量
n:返回的文档数量
millis:耗时(毫秒)
indexBounds:所使用的索引
例如
>db.order.ensureIndex({"user.uid":1})
>db.order.find({ "status": 1.0, "user.uid": { $gt: 2663199.0 } }).explain()
{
"cursor" : "BtreeCursor user.uid_1",
"nscanned" : 337800,
"nscannedObjects" : 337800,
"n" : 337800,
"millis" : 1371,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"user.uid" : [
[
2663199,
1.7976931348623157e+308
]
]
}
}
2、优化器profile
在MySQL中慢查询日志是经常作为我们优化数据库的依据那在MongoDB中是否有类似的功能呢?答案是肯定的那就是MongoDBDatabaseProfiler。所以MongoDB不仅有而且还有一些比MySQL的SlowQueryLog更详细的信息。
mongodb把要输出的慢语句,存在于db.system.profile。与mysql的slowlog配置相似,需要进行参数设置,mongo才会输出慢语句到profile。有两个参数来控制profile的输出
db.setProfilingLevel(level,slowms);
默认为0 不输出 1按第二个参数时间阀值(单位为毫秒)输出 2全部输出。通常我们在调优的时候都在测试环境打开参数。在生产环境下一般不输出profile。
比如
> db.system.profile.find({millis:{$gt:1000}})
就可以输出,查询时间大于1秒的慢语句。
profile输出的各项值的含义是
ts:命令执行时间
info:命令的内容
query:代表查询
order.order: 代表查询的库与集合
reslen:返回的结果集大小,byte数
nscanned:扫描记录数量
nquery:后面是查询条件
nreturned:返回记录数及用时
millis:所花时间
如果发现时间比较长,那么就需要作优化。
比如
(1)、nscanned数很大,或者接近记录总数,那么可能没有用到索引查询。
(2)、reslen很大,有可能返回没必要的字段。
(3)、nreturned很大,那么有可能查询的时候没有加限制。
三、MongoDB的索引选择机制
MongoDB的优化程序会在对比中选择更优秀的索引。
首先,它会给查询做一个初步的“最佳索引”;
其次,假如这个最佳索引不存在它会做尝试来选出表现最好的索引;
最后,优化器还会记住所有类似查询的选择(只到大规模文件变动或者索引上的变动)。
那么优化器是如何定义查询的“最佳索引”。最佳索引必须包含查询中所有可以做过滤及需要排序的字段。此外任何用于范围扫描的字段以及排序字段都必须排在做等值查询的字段之后。如果存在不同的最佳索引,那么Mongo将随机选择。
四、MongoDB的索引总结
1. 等值测试
索引中加入所有需要做等值测试的字段,任意顺序。
2. 排序字段(多排序字段的升/降序问题 )
根据查询的顺序有序的向索引中添加字段。
3. 范围过滤
以字段的基数(Collection中字段的不同值的数量)从低到高的向索引中添加范围过滤字段。
4、如果索引中的等值或者范围查询字段不能过滤出Collection中90%以上的文档,那么把它移除索引估计会更好一些。
5、索引使得可以通过关键字段获取数据,能够使得快速查询和更新数据。但是,必须注意的是,索引也会在插入和删除的时候增加一些系统的负担。往集合中插入数据的时候,索引的字段必须加入到B-Tree中去,因此,索引适合建立在读远多于写的数据集上,对于写入频繁的集合,在某些情况下,索引反而有副作用。不过大多数集合都是读频繁的集合,所以集合在大多数情况下是有用的。
6、如果数据集合比较小(通常小于4M),使用sort()而不需要建立索引就能够返回数据。在这种情况下,做好联合使用limit()和sort()。
热门推荐
- idea项目中tomcat的配置(tomcat部署项目以及与IDEA集成的实现)
- C#中List和数组之间的转换
- iis服务器安装错误(IIS7.0配置过程中出现HTTP 错误 403.14的解决方法)
- python实现的数据结构(Python嵌套式数据结构实例浅析)
- SQL中FOR XML PATH
- dedecms发布时间调整(织梦DEDECMS发布完文章没有显示文章内容解决办法)
- .NET开发中应该遵循的几个规则
- 宝塔面板密码忘了怎么找回(忘记宝塔面板登录地址安全入口后缀找回方法)
- 怎样解除阿里云账号(如何注销阿里云账号 阿里云账号注销图文教程)
- python获取网关ip地址(python实现扫描局域网指定网段ip的方法)