提高IXSCAN性能的方法?

4

我有一个查询语句的执行时间非常长。查询语句:

db.legs.find(
  {
    effectiveDate: {$lte: startDate},
    discontinuedDate: {$gte: startDate}
  }
).count()

以下是我的日志输出:

2016-11-21T08:58:50.470-0800 I COMMAND  [conn2] command myDB.legs 
command: count { count: "legs", query: { effectiveDate: { $lte: new Date(1412121600000) }, discontinuedDate: { $gte: new Date(1412121600000) } }, fields: {} } 
planSummary: IXSCAN { discontinuedDate: 1 } keyUpdates:0 writeConflicts:0 numYields:82575 reslen:47 locks:{ Global: { acquireCount: { r: 165152 } }, MMAPV1Journal: { acquireCount: { r: 82576 } }, Database: { acquireCount: { r: 82576 } }, Collection: { acquireCount: { R: 82576 } } } protocol:op_command 13940ms

我在{effectiveDate: 1, discontinuedDate: 1}上建立了索引,并使用IXSCAN获取数据。 我想知道是否有人能提出任何加速此查询的方法? 在这种情况下,IXSCAN不是我们可以期望的最快操作吗?


explain方法告诉我们什么? db.legs.explain(1).find({effectiveDate: {$lte:... 这是你查询的其余部分。 - Alex Blex
@AlexBlex 这是一段相当长的代码,但你可以在这里查看它: http://pastebin.com/wknw8AMm - Abe Miessler
你的索引是什么? - hyades
@hyades 我在原始问题中提到了我认为相关的索引。还有其他几个,但我不认为它们适用于此查询。您仍然希望我发布它们吗? - Abe Miessler
是的,我看到了解释输出中的其他索引。想确认一下,如果这些字段上也有单独的索引,因为最终会使用交集。 - hyades
显示剩余2条评论
2个回答

3

explain的输出并没有什么帮助,因为查询中的日期与“1/1/2015”这样的字符串进行比较,导致没有匹配项。

由于您有2个范围过滤器,索引交集不起作用,所以基本上Mongo使用1个索引,获取文档,并应用第二个过滤器。它仍然可以用于覆盖查询,但是尝试一次完全没有索引的查询可能是一个更好的主意:

db.legs.find({
    effectiveDate: {$lte: startDate},
    discontinuedDate: {$gte: startDate}
})
.hint({$natural:true})
.count()

尽管它执行COLLSCAN操作,但它使用COUNT阶段而不是FETCH阶段,这可能更快。


0

将日期ms存储在新字段中,并在同一字段上应用过滤器。同时传递输入日期转换为ms并应用过滤器,这样可以更快地完成操作。获取日期转换为ms的链接 epochconverter


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