【问题标题】:alternate mongo aggregate query备用 mongo 聚合查询
【发布时间】:2015-03-20 09:35:39
【问题描述】:

我有一个聚合的 mongodb 查询

db.collection.aggregate([
    {$match: {a: "a1", b: "b1"}},{$group: {...}}, 
    {$sort: {...}}, {$limit: {10}}
])

我在a和b上有一个复合索引,查询速度很快。

但是当我将匹配更改为

 $match: {$or: [{a: "a1", b: "b1"}, {a: "a2", b: "b2"}]}

查询变得很慢,而且似乎没有使用任何索引。

有什么方法可以 1)重写查询以使用复合索引(作为单个查询)或 2)强制它使用索引?

【问题讨论】:

  • 如果您定义了 db.coll.createIndex({a : 1, b: 1}) ,您的查询将正确使用复合索引
  • 我是这么认为的,但这不是它告诉我的解释。它没有使用带有 $or 的索引,但它没有使用。
  • 您能否发布explain 查询结果并修改您的代码以包含您执行sort 操作的字段。
  • 因为有人问我这个问题,我可以说在一个简单的测试中我没有看到超过 1,000,000 次操作的降级,所以看看结果大小会很有趣。确实,从聚合中“解释”的计划并没有明确说明使用了索引。但是,我没有看到性能下降表明它没有被使用。所以对我来说它很快。在不让我们搜索代码的情况下,您能否发布一些指标来说明您在问题中的差异?
  • 您使用的是哪个特定版本的 MongoDB 服务器?您能否还包括db.collection.find(...).explain(true) 的输出,以便我们可以看到为您的$or 查询考虑的查询计划?

标签: mongodb indexing aggregation-framework


【解决方案1】:

我会尝试在聚合的开头添加一个排序步骤,看看它是否会强制使用您的索引。

db.collection.aggregate([
    {$sort: {a:1, b:1}},
    {$match: {$or: [{a: "a1", b: "b1"}, {a: "a2", b: "b2"}]}},
    ...
])

【讨论】:

  • 虽然将 $sort 放在管道的开头可能会影响所选索引,但这肯定不是您想要的结果。聚合管道只能在第一阶段访问索引,因此任何后续阶段都无法使用索引,并且失去了使用索引边界的好处。 $match 应该几乎总是任何聚合管道的第一阶段。
  • @Neil-Lunn,很高兴了解索引和 $match,但为什么问题中的索引无法正常工作?
  • @Disposer 老实说不知道,明天可能会搜索代码以找出原因。这不是解决问题的方法,这就是我标记的全部内容..
  • @NeilLunn 在 MongoDB 2.6 中有一个 $sort + $match sequence optimisation,因此如果这是管道中的前两个操作,则顺序可能没有实际意义。需要知道服务器版本和候选索引以缩小答案的表面积;)
  • @Stennie 虽然它被“列为”优化,但它只会将$match 移动到$sort 之前,因此实际上是一个“代码更正”,并回到了我所说的观点。至于服务器版本,OP 引用“但这不是它用解释告诉我的”,所以说 2.6.x 是合理的,即使我相信解释选项存在于 2.4.9 中但没有记录。所以我认为大多数人甚至都没有尝试过早期版本。但那里可能是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2021-06-19
  • 1970-01-01
相关资源
最近更新 更多