MongoDB 复杂索引

标签 mongodb database-performance query-performance indices

我正在尝试了解如何最好地使用 MongoDB 中的索引。假设我有一组这样的文档:

{
  _id:        1,
  keywords:   ["gap", "casual", "shorts", "oatmeal"],
  age:        21,
  brand:     "Gap",
  color:     "Black",
  gender:    "female",     
  retailer:  "Gap",
  style:     "Casual Shorts",
  student:    false,
  location:  "US",
}

我定期运行查询以查找与每个字段的一组条件匹配的所有文档,例如:

db.items.find({ age:      { $gt: 13, $lt: 40 },
                brand:    { $in: ['Gap', 'Target'] },
                retailer: { $in: ['Gap', 'Target'] },
                gender:   { $in: ['male', 'female'] },
                style:    { $in: ['Casual Shorts', 'Jeans']},
                location: { $in: ['US', 'International'] },
                color:    { $in: ['Black', 'Green'] },
                keywords: { $all: ['gap', 'casual'] }
              })

我想知道我可以创建什么样的索引来提高此类查询的速度。我应该像这样创建一个复合索引吗:

db.items.ensureIndex({ age: 1, brand: 1, retailer: 1, gender: 1, style: 1, location: 1, color: 1, keywords: 1})

或者我是否可以创建一组更好的索引来优化此查询?

最佳答案

Should I create a compound index like this:

db.items.ensureIndex({age: 1, brand: 1, retailer: 1, gender: 1, style: 1, location: 1, color: 1, keywords: 1})

您可以像上面那样创建一个索引,但您几乎是在为整个集合建立索引。索引占用空间;索引中的字段越多,使用的空间就越多。通常是 RAM,尽管它们可以被换出。它们还会招致写入惩罚。

您的索引看起来很浪费,因为可能仅索引其中的几个字段将使 MongoDB 扫描一组接近查找操作预期结果的文档。

Is there a better set of indices I can create to optimize this query?

就像我之前说的,可能是的。但是这个问题在不知道集合细节的情况下很难回答,比如它有多少文档,每个字段可以有哪些值,这些值在集合中如何分布(50% 性别男性,50% 性别女性?) ,它们如何相互关联等。

有几种索引策略,但通常您应该努力创建具有高选择性的索引。选择将帮助 MongoDB 扫描“合理”数量的所需文档的“小”字段组合。同样,“小”和“合理”将取决于您正在执行的集合和查询的特征。

由于这是一个相当复杂的主题,这里有一些引用资料可以帮助您构建更合适的索引。

http://emptysqua.re/blog/optimizing-mongodb-compound-indexes/ http://docs.mongodb.org/manual/faq/indexes/#how-do-you-determine-what-fields-to-index http://docs.mongodb.org/manual/tutorial/create-queries-that-ensure-selectivity/

并使用 cursor.explain 评估您的索引。

http://docs.mongodb.org/manual/reference/method/cursor.explain/

关于MongoDB 复杂索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20338243/

相关文章:

mysql - 如何重写SQL查询以在MariaDB和MySQL上实现相同的性能

mysql 分区

MySQL UPDATE 性能...更快

mysql - 在 WHERE 子句中使用 OR 进行慢速 JOIN 查询 - 缺少可能的索引?

javascript - Mongodb 返回旧集合

MySQL 端口还是套接字?

python - 如何使用 PyMongo 迭代和更新文档?

mysql - SELECT * 和 SELECT 显式列之间是否存在运行时差异?

mongodb - 如何在服务器上执行 mongodump 并使用 golang 将其传输到本地计算机?

javascript - 还有比redirect()和render()更好的函数吗? 【 Node 应用】