Я пытаюсь оптимизировать агрегированный запрос, который просто дает две суммы и счет. Моя коллекция foo
имеет индекс:
db.foo.createIndex ( { 'info.x' : 1, 'bar.y' : 1, 'info.z' : 1 }, { background : true, name : 'foo_search_2' } );
Таким образом, все 3 из этих полей (и только эти поля) используются в моем совокупном запросе:
{ '$match' => { 'info.z' : 'Y' },
{ '$group' =>
{
_id : {},
x : { '$sum' => '$info.x' },
y : { '$sum' => '$bar.y' },
count : { '$sum' => 1 },
},
},
с подсказкой использовать foo_search_2 - он использует индекс, но все еще проверяет каждый документ!
[conn15381] command mydb.foo command: aggregate { aggregate: "foo", pipeline: [ { $match: { info.z: "Y" } }, { $group: { count: { $sum: 1 }, _id: {}, x: { $sum: "$info.x" }, y: { $sum: "$bar.y" } } } ], cursor: {}, hint: "foo_search_2", $readPreference: { mode: "secondaryPreferred" }, $db: "foo" } planSummary: IXSCAN { info.x: 1, bar.y: 1, info.z: 1 } keysExamined:79024 docsExamined:79024 cursorExhausted:1 numYields:761 nreturned:1 reslen:185 locks:{ Global: { acquireCount: { r: 1536 } }, Database: { acquireCount: { r: 768 } }, Collection: { acquireCount: { r: 768 } } } protocol:op_query 14147ms
без подсказки, он не использует индекс и проверяет все документы и на самом деле быстрее:
[conn15382] command mydb.foo command: aggregate { aggregate: "unit", pipeline: [ { $match: { info.z : "Y" } }, { $group: { _id: {}, count: { $sum: 1 }, x : { $sum: "$info.x" }, y: { $sum: "$bar.y" } } } ], cursor: {}, allowDiskUse: true, $readPreference: { mode: "secondaryPreferred" }, $db: "arrakis" } planSummary: COLLSCAN keysExamined:0 docsExamined:79024 cursorExhausted:1 numYields:720 nreturned:1 reslen:185 locks:{ Global: { acquireCount: { r: 1454 } }, Database: { acquireCount: { r: 727 } }, Collection: { acquireCount: { r: 727 } } } protocol:op_query 12526ms
Что я делаю неправильно? Я ожидаю, что все значения, которые я хочу, будут в индексе, чтобы не нужно было проверять документы.
Спасибо