Индекс Монго не используется - PullRequest
2 голосов
/ 14 февраля 2012

Я создал индекс из нескольких элементов для конкретного запроса, который я делаю:

{
    "v" : 1,
    "key" : {
        "MODIFIED" : -1,
        "state" : 1,
        "fail" : 1,
        "generated" : 1
    },
    "ns" : "foo.bar",
    "name" : "MODIFIED_-1_state_1_fail_1_generated"
}

Однако, когда я выполняю свой запрос, он не появляется, чтобы использовать мой индекс.Не могли бы вы рассказать, что я делаю неправильно?

Спасибо!

db.foo.find(    {
    "$or": [
        {
            "MODIFIED": {
                "$gt": {
                    "sec": 1321419600,
                    "usec": 0
                }
            }
        },
        {
            "$or": [
                {"state": "ca"},
                {"state": "ok"}
            ]
        }
    ],
    "$and": [
        {"fail": {"$ne": 1}},
        {"generated": {"$exists": false}}
    ]
}).explain();
{
    "cursor" : "BasicCursor",
    "nscanned" : 464215,
    "nscannedObjects" : 464215,
    "n" : 0,
    "millis" : 7549,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}

1 Ответ

7 голосов
/ 14 февраля 2012

Есть веская причина, по которой ваш индекс не может быть использован для вашего запроса, и я также думаю, что есть некоторые проблемы с самим запросом. Причина, по которой он не попадает в индекс, заключается в том, что между прочим вложенный $ или оператор, но я думаю, что вашей настоящей проблемой является отсутствие понимания всех операторов, доступных вам в MongoDB:

Прежде всего, ваш вложенный $ или проверить, является ли состояние "ca" или "ok", необязательным и (поскольку это главная причина, по которой вы не попали в индекс) можно заменить на state:{$in:["ca", "ok"]} который делает то же самое. Теперь ваш запрос:

db.foo.find(    {
    "$or": [
        {
            "MODIFIED": {
                "$gt": {
                    "sec": 1321419600,
                    "usec": 0
                }
            }
        },
        {
            state:{$in:["ca", "ok"]}            
        }
    ],
    "$and": [
        {"fail": {"$ne": 1}},
        {"generated": {"$exists": false}}
    ]
}).explain();

И это поразит ваш индекс. Ваша вторая проблема заключается в том, что $ и $ верхнего уровня не нужны. Обратите внимание, что AND(OR(A, B), AND(C, D)) = AND(OR(A, B), C, D). Этот запрос делает то же самое:

db.foo.find(    {
    "$or": [
        {
            "MODIFIED": {
                "$gt": {
                    "sec": 1321419600,
                    "usec": 0
                }
            }
        },
        {
            state:{$in:["ca", "ok"]}            
        }
    ],

    "fail": {"$ne": 1},
    "generated": {"$exists": false}

}).explain();

Который все еще попадает в индекс:

{
        "clauses" : [
                {
                        "cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi",
                        "nscanned" : 0,
                        "nscannedObjects" : 0,
                        "n" : 0,
                        "millis" : 1,
                        "nYields" : 0,
                        "nChunkSkips" : 0,
                        "isMultiKey" : false,
                        "indexOnly" : false,
                        "indexBounds" : {
                                "MODIFIED" : [
                                        [
                                                {
                                                        "$maxElement" : 1
                                                },
                                                {
                                                        "sec" : 1321419600,
                                                        "usec" : 0
                                                }
                                        ]
                                ],
                                "state" : [
                                        [
                                                {
                                                        "$minElement" : 1
                                                },
                                                {
                                                        "$maxElement" : 1
                                                }
                                        ]
                                ],
                                "fail" : [
                                        [
                                                {
                                                        "$minElement" : 1
                                                },
                                                1
                                        ],
                                        [
                                                1,
                                                {
                                                        "$maxElement" : 1
                                                }
                                        ]
                                ],
                                "generated" : [
                                        [
                                                null,
                                                null
                                        ]
                                ]
                        }
                },
                {
                        "cursor" : "BasicCursor",
                        "nscanned" : 0,
                        "nscannedObjects" : 0,
                        "n" : 0,
                        "millis" : 1,
                        "nYields" : 0,
                        "nChunkSkips" : 0,
                        "isMultiKey" : false,
                        "indexOnly" : false,
                        "indexBounds" : {

                        }
                }
        ],
        "nscanned" : 0,
        "nscannedObjects" : 0,
        "n" : 0,
        "millis" : 1
}

Надеюсь, это поможет! Кстати, немного более привычно начинать первый ключ в вашем составном индексе с порядка 1, а второй с -1. Обратите внимание, что -1 используется только для определения направления относительно предыдущего поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...