为什么即使集合有索引,explain查询输出仍然给出BasicCursor?

3
我有一个名为“stocks”的集合,在其中创建了一个复合索引,如下所示:
db.stocks.ensureIndex({"symbol":1,"date":1,"type": 1, "isValid": 1,"rootsymbol":1,"price":1},{"unique" : false})

我已经设置了分析级别,以便找出所有缓慢的查询。

其中一个查询所用时间为38毫秒,当对其进行解释时,结果如下:

抱歉,我已更新我的问题。

db.stocks.find({ query: { symbol: "AAPLE", date: "2014-01-18", type: "O", isValid: true }, orderby: { price: "1" } }).explain();
{
        "cursor" : "BasicCursor",
        "nscanned" : 705402,
        "nscannedObjects" : 705402,
        "n" : 0,
        "millis" : 3456,
        "indexBounds" : {

        }
}

我的问题是,即使它有索引,为什么它仍然显示为BasicCursor?

解释器不接受查询... - Sammaye
@Sammaye,我已经更新了我的问题。我把这个放在了find里面。 - Pawan
3个回答

4
我相信问题出在你使用了find()函数上。你指定了一个query参数,并在其中放置了你的搜索条件。我认为你不需要实际放置query。只需插入你的搜索条件。像这样:
db.stocks.find({ 
  symbol: "AAPLE", 
  date: "2014-01-18", 
  type: "O", 
  isValid: true 
}).sort( { "price": 1} ).explain();

请注意我的排序更改。您可以在这里阅读有关游标排序的更多信息。


我遇到了一个问题:Tue Sep 10 11:55:17 SyntaxError: missing ) after argument list (shell):0 - Pawan
啊哈...呵呵...我想这是你的orderby语法问题。看一下我的更新答案... - Lix
Lix,这个方法可行,现在我得到了“BtreeCursor”,但是为什么系统配置实际上会将查询打印为order by? - Pawan
@pre - 我对此并不确定。我在性能分析器方面没有太多经验。 - Lix
问题在于将查询操作符与函数操作符一起使用,这是一个错误。 - Sammaye

1

由于实际问题没有被描述,我将继续进行描述。

您正在使用函数运算符调用顶级查询运算符。例如,在此处调用查询运算符:

{ query: { symbol: "AAPLE", date: "2014-01-18", type: "O", isValid: true }, orderby: { price: "1" } }

queryorderby形式出现,但是你需要调用一个函数操作符:explain();。这是MongoDB已知的一个bug,这两个操作符不能很好地配合使用,因此会产生你所得到的输出结果。当然,当查询进入并被MongoDB解析时,它会记录在配置文件中,包括查询操作符queryorderbymaxscan等。这在调用命令时会更成为一个问题。参考:MongoDB $query operator ignores index?我找不到实际的JIRA,但这是相关的。编辑:我认为这可能是它的大致表示方式:https://jira.mongodb.org/browse/SERVER-6767

0

语法不是问题。为了让MongoDB使用复合索引(即包含多个字段的索引),查询/排序中的字段必须是索引字段的前缀。在这种情况下,您的索引包括以下字段:symbol、date、type、isValid、rootsymbol和price。您的查询/排序包括除rootsymbol之外的所有字段,因此无法使用该索引。可能的解决方案:

  • 从索引中删除rootsymbol,或者
  • rootsymbol添加到您的查询中,或者
  • 如果您不能执行上述任何操作,请创建另一个不包含rootsymbol的索引

参考

关于语法,实际上有一种查询语法不能使用索引:$where子句需要评估内联JavaScript,因此无法使用索引。例如:

db.collection.find( { $where: "field1.value > field2.value" } )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接