Několik klíčových bodů z výstupu plánu vysvětlení:
- Dotaz se týká následujících atributů:
siteId, status, creationDate, reportCount, assignee, parent
- Vítězný plán má dvě fáze:
- IX_SCAN používá
creationDate_1_reportCount_1_label_1
, používá indexované vyhledávání nacreationDate
areportCount
k identifikaci 56 dokumentů, které jsou poté předány do fáze NAČTENÍ - FETCH přijme 56 dokumentů z fáze IX_SCAN a poté tyto dokumenty načte, aby použil
siteId
,status
,assignee
aparent
filtry. Tento výslech způsobí vyřazení 37 dokumentů, což má za následek vrácení 19 dokumentů.
- IX_SCAN používá
Váš index tedy pokrývá pouze 2 ze 6 atributů ve vašem dotazu a zbývající 4 atributy ve vašem dotazu se použijí prozkoumáním dokumentů nikoli index . Pokud chcete, aby byl tento dotaz plně pokryt indexem, vytvořte následující index:
db.collection.createIndex(
{siteId: 1, status: 1, creationDate: 1, reportCount: 1, assignee: 1, parent: 1}
)
Pokud znovu spustíte s tímto indexem na místě, měli byste zjistit, že (a) MongoDB vybere tento index a (b) počet dokumentů předávaných fází IX_SCAN je stejný jako počet dokumentů vrácených vaším voláním find.
Říkám „měl bych najít“ protože zde existují další aspekty, které mohou vést k tomu, že MongoDB zvolí jiný index, např. použití $nor
a fázi řazení (creationDate: 1
). Doporučil bych vyladit index a po každém vylepšení spustit s vysvětlením „on“ a hledat tyto klíčové položky v executionStats
dílčí dokument:
- "nReturned"
- "totalKeysExamined"
- "totalDocsExamined"
Jednoduché pravidlo zní:čím blíže totalKeysExamined
je nReturned
a tím bližší totalDocsExamined
je nula ... tím lepší je pokrytí indexem.
Je zde také otázka nákladů na index (z hlediska dopadu na dobu zápisu a ukládání indexu), takže bych navrhoval zvážit vaše nefunkční požadavky – lze požadovaných uplynulých časů dosáhnout bez plného pokrytí indexem? Pokud ne, měli byste pokračovat v empirickém testování, ale buďte připraveni upravit svou volbu v reakci na to, co explain()
výstup vám řekne.