当前位置: 首页 > 知识库问答 >
问题:

为什么MongoDB只会在我使用提示时使用我的索引

洪承天
2023-03-14

我有一个带有索引的ISODate()类型字段的数据库(我也用字符串字段尝试了这个实验——结果相同)。我使用的是MongoDB(4. x)的开源版本,当我进行查询/排序以查找最大_finish_time时,除非我指定提示,否则不会使用索引。

我的问题是:

db.getCollection("test").find({}, { _finish_time: 1}).sort({_finish_time: -1}).limit(1)

这解释为:

{ 
    "queryPlanner" : {
        "plannerVersion" : 1.0, 
        "namespace" : "vdm-service-ts-staging.test", 
        "indexFilterSet" : false, 
        "parsedQuery" : {

        }, 
        "winningPlan" : {
            "stage" : "PROJECTION", 
            "transformBy" : {
                "_finish_time" : 1.0
            }, 
            "inputStage" : {
                "stage" : "SORT", 
                "sortPattern" : {
                    "_finish_time" : -1.0
                }, 
                "limitAmount" : 1.0, 
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR", 
                    "inputStage" : {
                        "stage" : "COLLSCAN", 
                        "direction" : "forward"
                    }
                }
            }
        }, 
        "rejectedPlans" : [

        ]
    }, 
    "serverInfo" : {
        "host" : "ip-10-82-245-45.us-west-2.compute.internal", 
        "port" : 27017.0, 
        "version" : "4.0.1", 
        "gitVersion" : "54f1582fc6eb01de4d4c42f26fc133e623f065fb"
    }, 
    "ok" : 1.0, 
    "operationTime" : Timestamp(1573220526, 1), 
    "$clusterTime" : {
        "clusterTime" : Timestamp(1573220526, 1), 
        "signature" : {
            "hash" : BinData(0, "blIkiGcam87SDdbKeZKex/9JXBU="), 
            "keyId" : NumberLong(6715502669504446467)
        }
    }
}

扫描整个收藏。当我为可用索引指定提示时,如:

db.getCollection("test").find({}, { _finish_time: 1}).sort({_finish_time: -1}).limit(1).hint("_finish_time")

我得到了查询计划:

{ 
    "queryPlanner" : {
        "plannerVersion" : 1.0, 
        "namespace" : "vdm-service-ts-staging.test", 
        "indexFilterSet" : false, 
        "parsedQuery" : {

        }, 
        "winningPlan" : {
            "stage" : "LIMIT", 
            "limitAmount" : 1.0, 
            "inputStage" : {
                "stage" : "PROJECTION", 
                "transformBy" : {
                    "_finish_time" : 1.0
                }, 
                "inputStage" : {
                    "stage" : "FETCH", 
                    "inputStage" : {
                        "stage" : "IXSCAN", 
                        "keyPattern" : {
                            "_finish_time" : -1.0
                        }, 
                        "indexName" : "_finish_time", 
                        "isMultiKey" : false, 
                        "multiKeyPaths" : {
                            "_finish_time" : [

                            ]
                        }, 
                        "isUnique" : false, 
                        "isSparse" : true, 
                        "isPartial" : false, 
                        "indexVersion" : 2.0, 
                        "direction" : "forward", 
                        "indexBounds" : {
                            "_finish_time" : [
                                "[MaxKey, MinKey]"
                            ]
                        }
                    }
                }
            }
        }, 
        "rejectedPlans" : [

        ]
    }, 
    "serverInfo" : {
        "host" : "ip-10-82-245-45.us-west-2.compute.internal", 
        "port" : 27017.0, 
        "version" : "4.0.1", 
        "gitVersion" : "54f1582fc6eb01de4d4c42f26fc133e623f065fb"
    }, 
    "ok" : 1.0, 
    "operationTime" : Timestamp(1573220603, 3), 
    "$clusterTime" : {
        "clusterTime" : Timestamp(1573220603, 3), 
        "signature" : {
            "hash" : BinData(0, "qsGhD1DpI306XbqtNZDYVINPid8="), 
            "keyId" : NumberLong(6715502669504446467)
        }
    }
}

它使用索引。我不想在查询中添加hint(),我对它为什么拒绝使用索引感到困惑。

我的索引是稀疏的,不是唯一的。

我尝试了其他索引并四处搜索,但在堆栈溢出或其他地方找不到任何关于这个问题的参考。

共有1个答案

冯阳华
2023-03-14

根据MongoDB的文件

如果稀疏索引会导致查询和排序操作的结果集不完整,则MongoDB不会使用该索引,除非hint()显式指定该索引。

要使用稀疏索引,请使用hint()显式指定索引

作为hint()强制查询优化器在执行查询时使用索引

 类似资料:
  • 如果我可以使用在一行中打印所需内容,那么我很难理解为什么我需要。

  • 我最近开始使用QUnit来单元测试我的JavaScript,我有点困惑的功能在那里留档:。 根据文档,设计用于: [s]指定在测试中预期运行多少个断言。 这是他们给出的例子: 我在这里唯一看到的是维护噩梦。每次向测试添加断言时,都必须更新该数字,否则测试将失败。这种功能是否有实际应用?

  • 我们正在使用jOOQ与包含以下表的MySQL数据库进行对话: 我们已经启用了对JSR-310类型的支持,所以我们在Java/Kotlin端使用来映射它。 注意选择如何在上进行筛选,但是结果表显示。 这是一个测试,在我的本地机器(UTC+10)上运行,对本地运行的标准Docker映像进行测试。 尽管使用了,但我认为我们遇到了一些时区问题,但是我不能通过直接讨论JDBC来重现这个问题。我尝试在其他测试

  • 将\u221a放入字符串并写入System.Out.Println语句应该会在屏幕上显示平方根符号。对吧?问题是,当我用mac(使用eclipse)这样做时,我会得到一个“?”而不是平方根符号。那是怎么回事?下面是一些示例代码来说明我的意思:

  • 我想知道为什么人们似乎不使用GraphQL jus与Redux。 我以前从未使用过GraphQL,但我想开始一个新项目,但阿波罗和继电器都不能说服我。目前,我正在创建一个使用react和redux以及“老式”RESTAPI的应用程序。我喜欢redux的想法,它将我的应用程序的全部信息存储在一个地方。 现在,据我所知,阿波罗和中继都做了类似的事情,但它们使用单独的存储,在这两者中,我们混合了逻辑和视