【问题标题】:Mongo $in with compound indexMongo $in 与复合索引
【发布时间】:2018-08-22 11:31:17
【问题描述】:

如何有效地对具有复合索引的集合进行$in 查找?

索引位于下面每个示例的字段 a 和 b 上。例如:db.foo.createIndex({a: 1, b: 1})

SQL 中的示例:

SELECT * 
FROM foo 
WHERE (a,b) 
  IN (
    ("aVal1", "bVal1"),
    ("aVal2", "bVal2")
  );

我知道你可以这样做:

db.foo.find( {
    $or: [
        { a: "aVal1", b: "bVal1" },
        { a: "aVal2", b: "bVal2" },
    ]
} )

使用$in 运算符是否有更高效的方法来执行此操作?

【问题讨论】:

  • 你的索引是什么?什么是样本文件?是什么让您相信 $in 是更好的方法?
  • @kmdreko 为问题添加了索引信息。一次查找数千条记录的 $or 语法似乎比在具有单个字段索引的集合上执行 $in 慢得多。我希望有一个更高效的解决方案。示例文档包含这两个键以及复合索引和其他一些数据(不确定其他数据与问题的相关性,但如果有,请告诉我,我可以添加更多详细信息)。

标签: mongodb


【解决方案1】:

由于您已经为(a, b) 创建了复合索引,因此索引支持所有子句表达式 -> mongo 将使用索引扫描而不是集合扫描。它可能已经足够快了。

参考:$or Clauses and Indexes

当评估 $or 表达式中的子句时,MongoDB 要么执行集合扫描,要么,如果索引支持所有子句,则 MongoDB 执行索引扫描。也就是说,为了让 MongoDB 使用索引来评估 $or 表达式,$or 表达式中的所有子句都必须由索引支持。否则,MongoDB 将执行集合扫描。

关于你的问题

有没有更高效的方法来使用 $in 操作符?

$in 匹配整个字段。如果要匹配(a,b),那么显然(a,b) 必须成为嵌入对象才能使用$in 进行搜索。

不确定制作嵌入式对象是否符合您当前的架构/要求。但如果是这样的话,$in has known for better performance comparing to $or:

当使用 $or 对同一字段的值进行相等检查时,请使用 $in 运算符而不是 $or 运算符。

在这种情况下,如果您有像 {e: {a: 'x', b: 'y'}} 这样的嵌入对象,那么 db.collections.createIndex({e: 1})$in 配对会加快速度

【讨论】:

    猜你喜欢
    • 2014-01-11
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多