私は私がする必要があるいくつかのユースケースでMongodb.aggregateは()インデックス
jobId: 1
result.status: 1
jobId: 1, result.status: 1
によってインデックスを有するおおよその構造その上で
{
"_id" : "job-id_00000001_2017-03-17T21:30:38.510Z",
"jobId" : "job-id",
"result" : {
"status" : "ok"
},
"..." : "..."
}
次でアーカイブされたタスクのコレクションを持っているが無視されます統計を頻繁に更新する(map:job-id - > status - > count)と、この集約関数を実行すると...
db.getCollection('jobs_archive').aggregate([
{$group: {
_id: {jobId: "$jobId", status: "$result.status"},
count: { $sum: 1 }
}}
], {explain: true})
... 1.2ミリの行で〜4秒実行され、これは許容できないほど長いです。 explain: true
ですべてのフィールドを私は...
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.jobs_archive",
"indexFilterSet" : false,
"parsedQuery" : {},
"winningPlan" : {
"stage" : "COLLSCAN",
"direction" : "forward"
},
"rejectedPlans" : []
}
を取得...とCOLLSCANはモンゴはそれにもかかわらず、インデックスからのデータを使用していないことを意味し、複合インデックスjobId: 1, result.status: 1
でご利用いただけます。
aggregate
クエリのパフォーマンスを最適化する方法はありますか?私は何か間違っているのですか?
(オリダルからの回答によってトリガ補遺)のドキュメントに多くの掘り後、私は「カバードクエリー」、私はそのような場合に使用されなければならないはずのような機能が気づきました。それはそうではないようです。 Aがクエリをカバーし https://docs.mongodb.com/manual/core/query-optimization/#covered-query
対象クエリは インデックスを使用して、完全に満足することができ、任意の書類を調査する必要はありませんクエリです。次の両方が適用されたときにインデックスが クエリをカバー:
- クエリ内のすべてのフィールドは結果で返されるすべてのフィールドが同じインデックスにあるインデックスの一部であり、
- 。
...
インデックスがクエリで必要なすべてのフィールドが含まれているため、MongoDBの は、クエリ条件に一致するだけ インデックスを使用して結果を返すことができます両方。
インデックスのみのクエリは、インデックス外のドキュメント のクエリよりもはるかに高速です。インデックスキーは通常カタログ化されている のドキュメントよりも小さく、索引は通常ディスクに順次配置されたRAMまたは で利用できます。IXSCAN/"INDEXNAME": "jobId_1_result.status_1"
winningPlan:IXSCAN /「INDEXNAMEモンゴ (1) db.getCollection('jobs_archive').find({"jobId" : "job-id"}).count() --> 0.375sec, count = 430000 (2) db.getCollection('archive').find({"jobId" : "job-id", "result.status": "ok"}).count() --> 1.400sec, count = 430000
explain()
から
よりすごみは
- winningPlanを語ります":" jobId_1 "
Mongoがインデックスを正しく使用する場合は、 'job-id + status'(6 * 5)の組み合わせごとに 'query()。count()'を使用しますが、この場合も。
RRRR ...私は両方のキー「JOBID + result.status」複合インデックスがcount()
のために使用されていない指定...と私は複合インデックスが使用され、クエリで一つだけjobId
を指定するとき注:Mongoの「バージョン」 : "3.4.2"、Ubuntuの16
は、なぜあなたは*思います参照してください
db.jobs_archive.find({jobId: n})
:
クエリオプティマイザは、次のパターンを使用してクエリの
{jobId: 1, result.status: 1}
インデックスを使用することができますか?私は彼らの文書を見て、そのような声明を見つけませんでした。代わりに、私は 'Covered Query'(私の質問の補遺参照)に関する注釈を見つけました。これはまさに私のケースですが、何らかの理由でうまくいかないようです。 –リファレンスドキュメントから引用した文章では正確に述べているためです。また、カバーされたクエリを使用していません。カバードクエリを使用するには、正確なインデックスフィールドに '$ match 'する必要があります。また、_idフィールドも除外してください。 –
' db.jobs_archive.explain()。aggregate({$ match:{jobId:1}}、 $ group:{idid:{jobId: "$ jobId"、ステータス: "$ result.status"}、件数:{$ sum:1}}}) 'と表示されます。 –