Jednopolový index MongoDB si můžete představit jako pole s ukazateli na umístění dokumentu. Pokud máte například kolekci s (všimněte si, že sekvence je záměrně mimo pořadí):
[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}
Jednopolní index
Nyní, pokud to uděláte:
db.collection.createIndex({a:1})
Index přibližně vypadá takto:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Všimněte si tří důležitých věcí:
- Je seřazeno podle
a
vzestupně - Každý záznam ukazuje na místo, kde se příslušné dokumenty nacházejí
- Index zaznamenává pouze hodnoty
a
pole.b
pole v indexu vůbec neexistuje
Pokud tedy uděláte dotaz jako:
db.collection.find().sort({a:1})
Vše, co musíte udělat, je projít rejstřík shora dolů, načíst a odeslat dokument, na který položky ukazují. Všimněte si, že index můžete také procházet zdola, např.:
db.collection.find().sort({a:-1})
a jediný rozdíl je v tom, že index procházíte obráceně.
Protože b
není v indexu vůbec, nemůžete index použít při dotazování na cokoli o b
.
Složený index
Ve složeném indexu, např.:
db.collection.createIndex({a:1, b:1})
Znamená to, že chcete třídit podle a
nejprve seřaďte podle b
. Index by vypadal takto:
[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1
Všimněte si, že:
- Index je řazen od
a
- V rámci každého
a
máte seřazenéb
- Máte 5 položek rejstříku oproti pouze třem v předchozím příkladu s jedním polem
Pomocí tohoto indexu můžete zadat dotaz jako:
db.collection.find({a:2}).sort({b:1})
Může snadno najít, kde a:2
pak jděte po indexu dopředu. Vzhledem k tomuto indexu to nemůžete udělat :
db.collection.find().sort({b:1})
db.collection.find({b:1})
V obou dotazech nemůžete snadno najít b
protože je rozprostřena po celém indexu (tj. ne v souvislých položkách). Jakkoli můžete udělat:
db.collection.find({a:2}).sort({b:-1})
protože v podstatě můžete najít, kde je a:2
jsou a projděte b
záznamy pozpátku.
Upravit :vysvětlení otázky @marcospgp v komentáři:
Možnost použití indexu {a:1, b:1}
abyste uspokojili find({a:2}).sort({b:-1})
ve skutečnosti dává smysl, pokud to vidíte z pohledu setříděné tabulky. Například index {a:1, b:1}
lze považovat za:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
najít({a:2}).sort({b:1})
Index {a:1, b:1}
znamená sort by a, then within each a, sort the b values
. Pokud poté provedete find({a:2}).sort({b:1})
, index ví, kde jsou všechny a=2
jsou. V rámci tohoto bloku a=2
, b
by byly seřazeny ve vzestupném pořadí (podle specifikace indexu), takže dotaz find({a:2}).sort({b:1})
lze uspokojit:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2
najít({a:2}).sort({b:-1})
Vzhledem k tomu, že po indexu lze chodit vpřed nebo vzad, byl použit podobný postup s malým otočením na konci:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block backward to satisfy
2 | 2 <-- find({a:2}).sort({b:-1})
2 | 3 <--
3 | 1
3 | 2
Skutečnost, že index lze procházet vpřed nebo vzad, je klíčovým bodem, který umožňuje dotaz find({a:2}).sort({b:-1})
abyste mohli používat index {a:1, b:1}
.
Vysvětlení Plánovače dotazů
Co plánovač dotazů plánuje, můžete vidět pomocí db.collection.explain().find(....)
. V podstatě pokud vidíte stage
z COLLSCAN
, pro dotaz nebyl použit nebo jej nelze použít žádný index. Viz vysvětlení výsledků
podrobnosti o výstupu příkazu.