`
wowo365
  • 浏览: 17649 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

mongodb 组合索引学习笔记

 
阅读更多

        查询mongo数据库 集合有120w 多的数据,集合大小是3G 多,有26个左右的字段,查询数据时,组合条件最多是8个,但是查出的数据,需要时间倒序排序。我把需要在查询的条件字段都建了组合索引,将需要排序的时间字段放到了最后面,mongdb的组合索引类似于mysql 的,组合索引的字段顺序是,把可选择性低的排在最左边,官网也没说具体怎么创建组合索引是最优的策略,因为这个需求自己根据应用情况多多做测试。建好组合索引后,查询8个条件,按时间倒序排序,分页取数据,耗时二三十毫秒。

 

几经周折,终于对mongo 的组合索引,有了点初步认识,总结如下:其中有个博客的内容对我帮助很大,罗列在这

 

    

mongo排序  http://ptc.35.com/?p=137

mongoDB中如果要对一个字段进行排序,而字段又没有索引的话,那就只能在内存中进行临时的sort了。DB的sort采用堆排序,如果limit数量比较少,

那排序的复杂度就是O(n*lgm), n是查询到的记录,m是limt数量。

mongoDB在无索引下sort, 会对总排序的记录大小有限制,就是排序记录的总size要小于32M, 否则会抛出异常。

默认db是从物理存储中得到记录的完整信息并放排序堆里,这样会导致速度偏慢。跟踪代码, 发现有一个可能可以值得优化的地方。

如果查询的时候设置了$returnKey”:1 (即查询只返回index字段)的话,那db就只把索引的值放到排序堆,而不会到记录的物理存储里读取内容,这样就减少了i/o的消耗。同时由于index字段的值比较少,可以在32M的限制下得到更大limit数量的排序。

在得到index的_id后,就可以根据id主键到DB从查出记录的详细内容。

注意这个方法必须要明确地设置特殊参数$returnKey”为1,而不能通过限制只返回index的字段来实现。

以上想法未经测试,仅供参考。有兴趣的同学可以测测看。


索引排序 优化 http://ptc.35.com/?p=214  http://ptc.35.com/?p=133

 

 

 

 

下面是照着官网翻译的:(翻译的有点生硬)

 

 

http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ

首先,索引在MongoDB中工作非常类似于在MySQL索引,因此许多技术来构建高效的索引在MySQL中适用于MongoDB。
其次,更重要的是知道索引上的这些建议只能带你走这么远,
对你的应用程序来说,最好的索引应该总是基于一些重要因素,包括你想要的各种查询
,读写比例,甚至在你的系统上的空闲内存数量

这意味着最好的索引策略,永远是剖析各种在数据集合上的指数配置,和你在生产环境中运行类似,并且看看
哪个效果好,没有什么能替代良好的实证分析。

 

注意:
索引策略
  1 创建符合你查询条件的索引
  2 一个查询一个索引
  3 请确保您的索引,可以适合在RAM中。
  4 要注意与低选择性的单一索引。
  5 使用explain 理解explain 输出的意思
  6 关注你系统中的读写比例
  7 索引属性
     1. The sort column must be the last column used in the index.
       
     2. The range query must also be the last column in an index. This is an axiom of 1 above.
     3. Only use a range query or sort on one column.
     4. Conserve indexes by re-ordering columns used on equality (non-range) queries.
     5. MongoDB's $ne or $nin operator's aren't efficient with indexes.

compound indexes can now be used to service queries where range or filter fields are used within the compound index, not just fields used from left to right.
复合索引现在可以用于服务查询范围或过滤字段中的使用复合索引,而不只是从左到右使用的字段。


db.foo.ensureIndex({a: 1, b: 1, c: 1})

1。排序列必须是索引中使用的最后一列。
   好:

     find(a=1).sort(a)
     find(a=1).sort(b)
     find(a=1, b=2).sort(c)

   坏:
     find(a=1).sort(c)
     尽管c是索引中的最后一列,但是a 是使用的最后一列,所以你只能安装a或b排序
    
2。范围查询,必须在最后一列索引,在1成立的基础上
   好:
     find(a=1,b>2)
     find(a>1 and a<10)
     find(a>1 and a<10).sort(a)
  
   坏:
      find(a>1, b=2)

3.只有一列使用范围查询或排序。
   好:
     find(a=1,b=2).sort(c)
     find(a=1,b>2)
     find(a=1,b>2 and b<4)
     find(a=1,b>2).sort(b)

    坏:
    find(a>1,b>2)
    find(a=1,b>2).sort(c)

http://www.mongodb.org/display/DOCS/Indexes

现在你可以使用复合索引服务于任何的,由构成索引字段组成的 等值查询和范围查询的组合查询

如果组合索引中的第一个键出现在查询语句中,那么该组合索引会被查询优化器选中;
如果组合索引中的第一个键不在查询语句中,那么只能通过hinted 方式让查询优化器选中。

虽然,组合索引可以用在,任何 由组合索引子集构成的查询 语句中
但是,对于一个查询语句,最优的索引优化规则是那些,查询字段在非查询字段之前的查询语句


高级查询http://www.mongodb.org/display/DOCS/Advanced+Queries
查询优化器http://www.mongodb.org/display/DOCS/Query+Optimizer 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics