Использование составного индекса MongoDB с $or

У нас есть составной индекс, такой как {a,b,c}, и запрос похож на

{$or:[{a: <value 1>, b: <value 2>}, {a: <value 2>, b: <value 1>}],  c: {$gte: <value c1>, $lte: <value c2>}}

Тогда индекс используется только частично, т.е.

indexBounds" : {
                            "a" : [
                                    [
                                            <value 1>,
                                            <value 1>
                                    ]
                            ],
                            "b" : [
                                    [
                                            <value 2>,
                                            <value 2>
                                    ]
                            ],
                            "c" : [
                                    [
                                            {
                                                    "$maxElement" : 1
                                            },
                                            {
                                                    "$minElement" : 1
                                            }
                                    ]

и другой аналогичный курсор с другой комбинацией значений. Результирующие данные будут отфильтрованы по 'c'. Таким образом, у нас больше nscannned и nscannedobjects, чем конечный результат. Если у нас есть запрос, как показано ниже

{$or:[{a: <value 1>, b: <value 2>, c: {$gte: <value c1>, $lte: <value c2>}}, {a: <value 2>, b: <value 1>, c: {$gte: <value c1>, $lte: <value c2>}}]} 

тогда индекс полностью используется, и у нас есть nscanned=n Вопрос - это нормальное поведение с $or, который пытается использовать индекс для чего-либо внутри выражения, а не для объединения всего запроса, или мы что-то упустили.


person PAVAN RANGAIN    schedule 18.10.2014    source источник


Ответы (1)


Это нормальное поведение. Планировщик запросов использует индекс { "a" : 1, "b" : 1, "c" : 1 } для выполнения предложения $or запроса в обоих случаях, поскольку планировщик решил, что это лучший (единственный?) способ выполнить запрос с индексом. Поскольку конъюнкция распределяется по дизъюнкции, (X OR Y) AND Z (структура вашего первого запроса) эквивалентна (X AND Z) OR (Y AND Z) (структура вашего второго запроса), но для последнего запроса лучше использовать индекс. Планировщик запросов не меняет логику запросов, и иногда есть лучший способ написать запрос, чтобы планировщик запросов мог максимально использовать индексы.

person wdberkeley    schedule 20.10.2014