Mongodb 针对null、false和true查询的复合mongo索引优化

Mongodb 针对null、false和true查询的复合mongo索引优化,mongodb,Mongodb,我正在尝试找出创建索引的最佳方法,mongo可以使用该方法加快查询速度: "query" : { "deleted_at" : null, "placed_at" : { "$exists" : true }, "exported_at" : null, "failed_export" : false } 目前,即使没有结果,也需要2-3分钟来检查表格。解释显示它正在浏览成千上万条记录,而不是使用索引 我试着运行这个: db.some_t

我正在尝试找出创建索引的最佳方法,mongo可以使用该方法加快查询速度:

"query" : {
    "deleted_at" : null,
    "placed_at" : {
        "$exists" : true
    },
    "exported_at" : null,
    "failed_export" : false
}
目前,即使没有结果,也需要2-3分钟来检查表格。解释显示它正在浏览成千上万条记录,而不是使用索引

我试着运行这个:

db.some_table.createIndex({deleted_at: -1, placed_at: 1, exported_at: -1, failed_export: -1}, {background: true})
之后运行查询时:

db.some_table.find({deleted_at: null, placed_at: {$exists: true}, exported_at: null, failed_export: false}).explain("executionStats")
我看到它使用了正确的索引,但速度非常慢。它正在检查所有330494行。以下是执行统计数据:

  "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 0,
            "executionTimeMillis" : 1585381,
            "totalKeysExamined" : 330494,
            "totalDocsExamined" : 330494,
            "executionStages" : {
                    "stage" : "FETCH",
                    "filter" : {
                            "$and" : [
                                    {
                                            "placed_at" : {
                                                    "$exists" : true
                                            }
                                    },
                                    {
                                            "deleted_at" : {
                                                    "$eq" : null
                                            }
                                    },
                                    {
                                            "exported_at" : {
                                                    "$eq" : null
                                            }
                                    },
                                    {
                                            "failed_export" : {
                                                    "$eq" : false
                                            }
                                    }
                            ]
                    },
获奖计划是:

           "winningPlan" : {
                    "stage" : "FETCH",
                    "filter" : {
                            "$and" : [
                                    {
                                            "placed_at" : {
                                                    "$exists" : true
                                            }
                                    },
                                    {
                                            "deleted_at" : {
                                                    "$eq" : null
                                            }
                                    },
                                    {
                                            "exported_at" : {
                                                    "$eq" : null
                                            }
                                    },
                                    {
                                            "failed_export" : {
                                                    "$eq" : false
                                            }
                                    }
                            ]
                    },
                    "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                    "placed_at" : 1
                            },
                            "indexName" : "placed_at_1",
                            "isMultiKey" : false,
                            "direction" : "forward",
                            "indexBounds" : {
                                    "placed_at" : [
                                            "[MinKey, MaxKey]"
                                    ]
                            }
                    }
            },
它确实列出了我在一个被拒绝的计划中创建的索引

你知道为什么它会浏览数据库中的每一条记录吗?这损害了我们的表现


我尝试了暗示正确的记录,但似乎没有多大帮助。

与其在:null处查询
已删除\u,不如创建一个新的
状态
字段或
已删除
字段,并配置应用服务器以填充该字段。然后,您可以在此字段上创建更有效的索引,以查找所有软删除的文档

白皮书:

避免查询中的否定。与大多数数据库系统一样,MongoDB不为缺少值的情况编制索引,否定条件可能需要扫描所有文档。如果否定是唯一的条件,并且不是选择性的(例如,查询订单表,其中99%的订单已完成,以确定尚未完成的订单),则需要扫描所有记录