問題は、どのインデックスも実際にソートされたクエリに役立たないことです。これが、スキャンされたオブジェクトの数が多く、SORT_KEY_GENERATOR
が存在する理由です。 ステージ(メモリ内ソート、32MBに制限)。
一方、並べ替えられていないクエリでは、{ category: 1, _id: 1 }
のいずれかを使用できます。 または{ category: 1, _id: 1, sticky: 1, lastPostAt: 1 }
インデックス。 1つにはプレフィックスが含まれているため、どちらかを使用することは完全に有効であることに注意してください。 他の。詳細については、プレフィックスを参照してください。
MongoDB find()
クエリは通常、1つのインデックスのみを使用するため、単一の複合インデックスがクエリのすべてのパラメータに対応する必要があります。これには、find()
の両方のパラメーターが含まれます。 およびsort()
。
インデックスの作成方法に関する優れた記事は、MongoDB複合インデックスの最適化にあります。複合インデックスの順序はequality->sort-> range である必要があるという、記事の要点を取り上げましょう。 :
クエリの「形状」は次のとおりです。
db.collection.find({category:..., _id: {$gt:...}})
.sort({sticky:-1, lastPostAt:-1, _id:1})
.limit(25)
わかります:
-
category:...
平等です -
sticky:-1, lastPostAt:-1, _id:1
並べ替え -
_id: {$gt:...}
範囲です
したがって、必要な複合インデックスは次のとおりです。
{category:1, sticky:-1, lastPostAt:-1, _id:1}
explain()
の勝利計画はどこにありますか 上記のインデックスを使用したクエリの出力は次のようになります。
"winningPlan": {
"stage": "LIMIT",
"limitAmount": 25,
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"category": 1,
"sticky": -1,
"lastPostAt": -1,
"_id": 1
},
"indexName": "category_1_sticky_-1_lastPostAt_-1__id_1",
"isMultiKey": false,
"multiKeyPaths": {
"category": [ ],
"sticky": [ ],
"lastPostAt": [ ],
"_id": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"category": [
"[ObjectId('5a779b31f4fa724121265142'), ObjectId('5a779b31f4fa724121265142')]"
],
"sticky": [
"[MaxKey, MinKey]"
],
"lastPostAt": [
"[MaxKey, MinKey]"
],
"_id": [
"(ObjectId('5a779b5cf4fa724121269be8'), ObjectId('ffffffffffffffffffffffff')]"
]
}
}
}
}
優勝プランにはSORT_KEY_GENERATOR
が含まれていないことに注意してください ステージ。これは、インデックスを十分に活用して、並べ替えられたクエリに応答できることを意味します。