MongoDB组合索引的优化

本文通过一个类Disqus评论系统的案例,探讨了MongoDB中组合索引的创建和优化,强调了索引顺序的重要性。通过explain()分析,解释了如何通过调整索引顺序减少查询扫描的文档数量,避免内存排序,提高查询效率。文章还介绍了MongoDB查询优化器的索引选择机制,提出了等值测试、排序和范围过滤的索引构建策略。
摘要由CSDN通过智能技术生成

A. Jesse Jiryu Davis —— 10gen工程师,从事MongoDB、Python及Tornado。在Dzone上分享了MongoDB中组合索引的最佳建立方法以及索引中字段的最优顺序。并通过explain()输出的结果来验证实际性能,同时还分析了MongoDB的查询优化器的索引选择机制。

项目背景

预想中的项目是在MongoDB上建立一个类Disqus的评论系统(虽然Disqus使用的是Postgres,但是不影响我们讨论)。这里储存的评论可能是上万条,但是我们先从简单的4条谈起。每条评论都拥有时间戳(timestamp)、匿名(发送)与否(anonymous)以及质量评价(rating)这三个属性:

 
 
 
  1. timestamp: 1, anonymous: false, rating: 3 }  
  2. timestamp: 2, anonymous: false, rating: 5 }  
  3. timestamp: 3, anonymous:  true, rating: 1 }  
  4. timestamp: 4, anonymous: false, rating: 2 } 

这里需要查询的是anonymous = false而且timestamp在2 – 4之间的评论,查询结果通过rating进行排序。我们将分3步完成查询的优化并且通过MongoDB的explain()对索引进行考量。

范围查询

首先从简单的查询开始 —— timestamps范围在2-4的评论:

 
 
 
  1. > db.comments.find( { timestamp: { $gte: 2, $lte: 4 } } ) 

查询的结果很显然是3条。然而这里的重点是通过explain()看MongoDB是如何去实现查询的:

 
 
 
  1. > db.comments.find( { timestamp: { $gte: 2, $lte: 4 } } ).explain()  
  2. {  
  3.     "cursor" : "BasicCursor",  
  4.     "n" : 3,  
  5.     "nscannedObjects" : 4,  
  6.     "nscanned" : 4,  
  7.     "scanAndOrder" : false 
  8.     // ... snipped output ...  

先看一下如何读MongoDB的查询计划:首先看cursor的类型。“BasicCursor”可以称得上一个警告标志:它意味着MongoDB将对数据集做一个完全的扫描。当数据集里包含上千万条信息时,这完全是行不通的。所以这里需要在timestamp上加一个索引:

 
 
 
  1. > db.comments.createIndex( { timestamp: 1 } ) 

现在再看explain()的输出结果:

 
 
 
  1. > db.comments.find( { timestamp: { $gte: 2, $lte: 4 } } ).explain()  
  2. {  
  3.     "cursor" : "BtreeCursor timestamp_1",  
  4.     "n" : 3,  
  5.     "nscannedObjects" : 3,  
  6.     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值