为什么我的mongo查询不仅仅使用索引?

时间:2013-09-02 11:13:19

标签: windows mongodb

请观察:

MongoDB shell version: 2.4.1
connecting to: test
> use dummy
switched to db dummy
> db.invoices.find({'items.nameTags': /^z/}, {_id: 1}).explain()
{
        "cursor" : "BtreeCursor items.nameTags_1_created_1_special_1__id_1_items.qty_1_items.total_1 multi",
        "isMultiKey" : true,
        "n" : 55849,
        "nscannedObjects" : 223568,
        "nscanned" : 223568,
        "nscannedObjectsAllPlans" : 223568,
        "nscannedAllPlans" : 223568,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 86,
        "nChunkSkips" : 0,
        "millis" : 88864,
        "indexBounds" : {
                "items.nameTags" : [
                        [
                                "z",
                                "{"
                        ],
                        [
                                /^z/,
                                /^z/
                        ]
                ],
                "created" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "special" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "_id" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "items.qty" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "items.total" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ]
        },
        "server" : "IL-Mark-LT:27017"
}
>

以下是索引的定义:

> db.system.indexes.find({name : 'items.nameTags_1_created_1_special_1__id_1_items.qty_1_items.total_1'}).pretty()
{
        "v" : 1,
        "key" : {
                "items.nameTags" : 1,
                "created" : 1,
                "special" : 1,
                "_id" : 1,
                "items.qty" : 1,
                "items.total" : 1
        },
        "ns" : "dummy.invoices",
        "name" : "items.nameTags_1_created_1_special_1__id_1_items.qty_1_items.total_1"
}
>

最后,这是一个示例发票文档(只有2个项目):

> db.invoices.findOne({itemCount: 2})
{
        "_id" : "85923",
        "customer" : "Wgtd Fm 91",
        "businessNo" : "314227928",
        "billTo_name" : "Wgtd Fm 91",
        "billTo_addressLine1" : "3839 Ross Street",
        "billTo_addressLine2" : "Kingston, ON",
        "billTo_postalCode" : "K7L 4V4",
        "purchaseOrderNo" : "boi",
        "terms" : "COD",
        "shipDate" : "2013-07-10",
        "shipVia" : "Moses Transportation Inc.",
        "rep" : "Snowhite",
        "items" : [
                {
                        "qty" : 4,
                        "name" : "CA 7789",
                        "desc" : "3 pc. Coffee Table set (Silver)",
                        "price" : 222.3,
                        "total" : 889.2,
                        "nameTags" : [
                                "ca 7789",
                                "a 7789",
                                " 7789",
                                "7789",
                                "789",
                                "89",
                                "9"
                        ],
                        "descTags" : [
                                "3",
                                "pc",
                                "c",
                                "coffee",
                                "offee",
                                "ffee",
                                "fee",
                                "ee",
                                "e",
                                "table",
                                "able",
                                "ble",
                                "le",
                                "e",
                                "set",
                                "et",
                                "t",
                                "silver",
                                "ilver",
                                "lver",
                                "ver",
                                "er",
                                "r"
                        ]
                },
                {
                        "qty" : 4,
                        "name" : "QP 8681",
                        "desc" : "Ottoman Bed",
                        "price" : 1179.1,
                        "total" : 4716.4,
                        "nameTags" : [
                                "qp 8681",
                                "p 8681",
                                " 8681",
                                "8681",
                                "681",
                                "81",
                                "1"
                        ],
                        "descTags" : [
                                "ottoman",
                                "ttoman",
                                "toman",
                                "oman",
                                "man",
                                "an",
                                "n",
                                "bed",
                                "ed",
                                "d"
                        ]
                }
        ],
        "itemCount" : 2,
        "discount" : "10%",
        "delivery" : 250,
        "hstPercents" : 13,
        "subTotal" : 5605.6,
        "totalBeforeHST" : 5295.04,
        "total" : 5983.4,
        "totalDiscount" : 560.56,
        "hst" : 688.36,
        "modified" : "2012-10-08",
        "created" : "2014-06-25",
        "version" : 0
}
>

我的问题是mongodb根据前面提到的explain()输出不使用索引。为什么?毕竟我只请求_id字段,这是索引的一部分。

总的来说,我觉得我做错了。我的发票集合有65,000张发票,总计3,291,092件。 explain()查询花了将近89秒。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

您正在使用数组和子文档。涵盖的索引不适用于其中任何一个。

来自mongo docs:

如果符合以下情况,索引无法覆盖查询:

  • 集合中任何文档中的任何索引字段都包含一个数组。如果索引字段是数组,则索引将成为多键索引索引,并且不支持覆盖查询。
  • 任何索引字段都是子文档中的字段。要索引子文档中的字段,请使用点表示法。例如,考虑具有以下形式的文档的集合用户:

http://docs.mongodb.org/manual/tutorial/create-indexes-to-support-queries/