3

运行 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 上的单个索引,explain 显示仅使用 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)], u'v': 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 文档测试语料库上性能非常慢。

4

2 回答 2

2

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

只需在游标上调用它:

cursor = collection.find({query-doc}).hint({index-fields})
于 2012-08-24T21:13:26.467 回答
1

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

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

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

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

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

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

于 2012-08-25T08:47:54.513 回答