MongoDB优化FindAndModify或Find + Sort

时间:2012-08-24 21:04:03

标签: python mongodb pymongo database

运行MongoDB,我试图将具有优先级(d)的三列密钥查找(a,b,c)排队。我有一个像(pymongo语法)的查询:

collection.find({'a':'foo','b':'bar','c':'baz'}, sort = [('d', -1)] )

使用复合索引(a + 1,b + 1,c + 1,d-1)运行解释显示全表扫描和BasicCursor。

在d上有一个索引,解释显示单独使用的索引。

对于大型表,我真正想要的是使用复合索引。我怎样才能做到这一点?

INDEX_INFORMATION: {u' id ':{u'key':[(u'_id',1)],u'v':1},  u'color_1_level_1_in_progress_1_Ranking_-1':{u'key':[(u'color',     1),    (u'level',1),    (u'in_progress',1),    (u'Ranking',-1)],   你好':1}}

EXPLAIN ON A FIND+SORT QUERY
db.coll.find({'level' : {'$in' : [0,1,2]}, 'in_progress' : 0, 'color' : {'$in' : ['Red', 'Blue', 'Green]} },  sort = [('Ranking', -1)] ).explain()

OUTPUT ON EXPLAIN
OperationFailure: database error: too much data for sort() with no index.  add an index or specify a smaller limit


THE QUEUEING QUERY I CARE ABOUT OPTIMIZING
coll.find_and_modify(
  query = {'level' : {'$in' : [0,1,2]}, 'in_progress' : 0, 'color' : {'$in' : ['Red', 'Blue', 'Green']} },
  sort = {'Ranking' : -1},                                                                                                                                                                             
  update = {'$set': {'in_progress': 1}} 
)   

请注意,当我在排序字段“排名”上添加索引时,解释会返回正在使用排名索引。但是从未使用复合索引,并且在1.5 MM文档测试语料库中性能非常慢。

2 个答案:

答案 0 :(得分:2)

有一种方法可以在执行查询时强制使用特定的索引,称为hint

只需在光标上调用它:

cursor = collection.find({query-doc}).hint({index-fields})

答案 1 :(得分:1)

Mongodb索引系统基于实验。基本上,查询优化器将使用所有可能的索引运行查询,并比较每个索引的时间。它将学习使用给定类型查询的最佳索引。 来自query optimizer上的文档:

  

在测试新计划时,MongoDB并行执行多个查询计划。一旦完成,它就会终止其他执行,并且系统已经知道哪个计划是好的

如果您的集合非常小,查询优化器选择的索引可能不是您认为最好的。但是,此查询和此集合的速度更快。 当你的收藏增长时,也许另一个索引会更合适。

在你的情况下,我认为mongo更容易扫描所有文档,然后用d上的索引对它们进行排序,因为你的文档很少。

尝试针对具有更多文档的集合(比如100万)运行相同的查询(多次使学习效率更高),您可能会看到它将使用完整索引。

因此,使用oe提示不是必要的(尽管不会有害)。我的建议:让mongo查询优化器完成它的工作: - )