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()。
热门推荐
- sqlserver栏位说明(SQL Server重置IDENTITY属性种子值操作)
- 微信小程序的交通码(微信小程序中实现车牌输入功能)
- div内容水平垂直居中的方法(不定宽高的文字在div中垂直居中实现方法)
- laravel命令行与可选项(Laravel6.0.4中将添加计划任务事件的方法步骤)
- jmeter接口性能测试教程(Xmeter API接口测试工具使用方法解析)
- php redis应用场景(PHP商品秒杀问题解决方案实例详解mysql与redis)
- thinkphp使用说明(thinkphp框架使用JWTtoken的方法详解)
- python炫酷烟花源代码(python实现浪漫的烟花秀)
- JavaScript 阻止超链接跳转的操作方法(多种写法)(JavaScript 阻止超链接跳转的操作方法多种写法)
- python中迭代器的作用(Python3.5迭代器与生成器用法实例分析)