MongoDB为什么是包含2dsphere的复合索引

时间:2017-10-18 15:03:52

标签: mongodb indexing mongodb-query

我创建了一个复合索引:

oradamis_vt

但是当我在下面运行查询时,MongoDB并没有考虑索引,而是制作了一个COLLSCAN。

version

完整结果如下:

versionNumber

聚苯乙烯。我只插入了4个文件。

为什么会这样?

sonIslemKullanici

上述查询结果:
https://gist.github.com/anonymous/8dc084132016a1dfe0efb150201f04c7

sonIslem

以上查询的结果: https://gist.github.com/anonymous/2b76c5a7b4b348ea7206d8b544c7d455

1 个答案:

答案 0 :(得分:0)

为了帮助理解MongoDB在这里做了什么,你可以:

  • 使用allPlansExecution mode运行explain并查看被拒绝的计划,了解MongoDB拒绝您的索引的原因
  • 使用.hint(_your_index_name_)运行查找,并将解释输出与原始(未提示)查找的输出进行比较。

这两者都是为了达到同样的目的,即;比较解释计划(1)使用COLLSCAN查找和(2)使用您的索引的查找。通过比较这些解释计划,您可能会看到一些差异,这解释了MongoDB决定不使用您的索引。

有关分析解释计划in the docs的详细信息。

如果您需要帮助确定MongoDB选择COLLSCAN的原因,您甚至可以使用比较计划更新您的OP。

更新1:查看您提供的解释计划......

plan使用您的索引,但解释计划输出...

        "inputStage" : {
            "stage" : "IXSCAN",
            "nReturned" : 4,
            "executionTimeMillisEstimate" : 0,
            "works" : 5,
            "advanced" : 4,
            ...,
            "keyPattern" : {
                "datetime" : -1,
                "location" : "2dsphere"
            },
            "indexName" : "datetime_-1_location_2dsphere",
            ...,
            "indexVersion" : 2,
            ...,
            "keysExamined" : 4,
            ...
        }

...表明它使用索引来检查4个索引键,然后将4个文档返回到FETCH阶段。这告诉我们索引没有提供任何选择性,并且选择性由遵循IXSCAN的FETCH阶段提供。这实际上是COLLSCAN所做的,但没有冗余的IXSCAN。这可能会说明为什么MongoDB更喜欢COLLSCAN但为什么IXSCAN什么都不做?我怀疑这是因为2dsphere索引不能用于回答在2dsphere字段上缺少地理谓词的查询。您的查询的谓词超过datetime,但没有location的地理谓词。我认为这意味着MongoDB不能使用2dsphere索引来回答datetime上的谓词。有关此in the docs背景的更多信息。简单地说,使用稀疏索引意味着索引中不一定存在集合中每个文档的条目,因此如果搜索时没有location属性,则MongoDB不能依赖索引来满足查询。

你可以通过......来测试这个断言是否正确。

  • 更新您的查询以在每个datetimelocation属性中包含谓词

  • 更新uur查询以仅在location attibute上包含谓词

...并且对于每个运行查询,然后检查解释计划输出以查看IXSCAN阶段是否实际选择了任何内容。如果IXSCAN阶段是选择性的,那么您应该在解释计划输出中看到键examined > nReturned(假设您传入的标准实际上选择了< 4个文档!)。