【问题标题】:How to improve mongoDb query performance?如何提高mongoDb查询性能?
【发布时间】:2019-02-22 10:13:06
【问题描述】:

我有一个名为 Codes 的集合。这就是Schema 的定义方式:

import mongoose from 'mongoose'
import autoIncrement from 'mongoose-auto-increment';

const Schema = mongoose.Schema;
const CodesSchema = mongoose.Schema(
  {
    configId: { type: Number },
    campaignId: { type: Number },
    permissions: {
      all: { type: Boolean, default: false },
      users: { type: [Number], default: [] }
    }
)

autoIncrement.initialize(mongoose.connection);
CodesSchema.plugin(autoIncrement.plugin, { model: 'Codes', field: 'campaignId' });
export default mongoose.model('Codes', CodesSchema)

有一个查询如下所示:

const query = {
  $and:[
    {$or: [
      {'permissions.all': true},
      {'permissions.users': 12}
    ]},
    {configId: 3}
  ]
};

Codes.find(query, (err, res) => {
  // do something with the result
})

这很好用,但是如果数据库中有大量文档,那么这个查询真的很慢。

我能做些什么来提高这个特定查询的性能吗?我认为createIndex 会有所帮助,但我不确定这是否可以应用,因为有$and$or 条件。

更新

我以这种方式添加了索引:

CodesSchema.index({configId: 1, 'permissions.all': 1, 'permissions.users': 1});

但是使用.explain('executionStats') 选项运行查询会返回:

{
    "executionSuccess" : true,
    "nReturned" : 6,
    "executionTimeMillis" : 0,
    "totalKeysExamined" : 10,
    "totalDocsExamined" : 10,
}

这似乎不对,因为检查的文档数量大于返回的文档数量。

【问题讨论】:

  • 可以的。尝试使用explain 检查索引使用情况
  • 我应该寻找indexFilterSet 吗?如果是,则设置为false
  • 不,您应该寻找 docs.mongodb.com/manual/indexes 。我猜是mongoosejs.com/docs/guide.html#indexes。你在用猫鼬,不是吗?
  • 是的,我正在使用猫鼬
  • 如果我将index: true 设置为configId 字段,那么这应该足以提高该查询的性能了吗?

标签: node.js mongodb mongoose mongodb-query database-performance


【解决方案1】:

索引本身是正确的。

必须是CodesSchema.index,而不是Code.index

确保您调用 Code.syncIndexes 来更新索引 dbside。

“解释”部分 - 你应该检查winningPlan

如果查询没有使用索引,它应该是这样的

    "winningPlan" : {
        "stage" : "COLLSCAN",
        "filter" : {

当索引被使用时,它会变为

    "winningPlan" : {
        "stage" : "FETCH",
        "inputStage" : {
            "stage" : "OR",
            "inputStages" : [ 
                {
                    "stage" : "IXSCAN",
                    "keyPattern" : {

【讨论】:

  • 检查winningPlan 表明所有索引都已使用。我尝试一一创建索引(而不是像提供的示例中那样使用多个索引)并且评估文档的总数减少了近 50%,但是 rejectedPlans 返回 1 个对象......错了吗?
  • 基本上我问的是当有被拒绝的计划时是否有问题
  • 请阅读文档docs.mongodb.com/manual/indexes,了解简单索引、复合索引和覆盖查询之间的区别。 RejectedPlans 是可能查询的列表。计划者尝试了所有这些以选择性能最高的一个。如果有不止一种方法可以完成查询,您将始终拥有它们。
  • 要提供附加信息,请注意索引大小和使用此索引的写入性能:由于您的 permissions.users 字段是一个数组,将为数组的每个元素创建一个索引条目,因此您的索引插入数据时会快速增长。此外,在对索引进行排序时,在该数组中添加/删除数据将导致索引部分重写。选择索引字段时请记住这一点。
猜你喜欢
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 2016-04-06
  • 2019-01-25
  • 1970-01-01
相关资源
最近更新 更多