Това са много въпроси в един пост;) Позволете ми да ги прегледам в практически ред :
- Всяка заявка може да използва най-много един индекс (с изключение на $или клаузи от най-високо ниво и други подобни). Това включва всяко сортиране.
- Поради горното определено ще ви трябва съставен индекс за вашия проблем, а не отделни индекси по поле.
- Полета с ниска кардиналност (така че полета с много малко уникални стойности във вашия набор от данни) обикновено не трябва да са в индекса, тъй като тяхната селективност е много ограничена.
- Редът на полетата във вашия съставен индекс има значение, както и относителната посока на всяко поле във вашия съставен индекс (напр. „{name:1, age:-1}“). В mongodb.org има много документация за съставните индекси и указанията на полетата на индекса, така че няма да повтарям всичко тук.
- Сортирането ще използва индекса само ако полето за сортиране е в индекса и е полето в индекса непосредствено след последното поле, използвано за избор на набора от резултати. В повечето случаи това би било последното поле на индекса.
Така че, изобщо не трябва да включвате състоянието във вашия индекс, тъй като след като индексното обхождане е елиминирало огромното мнозинство от документи въз основа на полета с по-висока мощност, в повечето случаи ще има най-много 2-3 документа, което едва ли е оптимизирано от индекс на състоянието (особено след като споменахте тези 2-3 документа е много вероятно да имат същия статус така или иначе).
Сега, последната бележка, която е уместна във вашия случай, е, че когато използвате заявки за диапазон (а вие сте), тя така или иначе няма да използва индекса за сортиране. Можете да проверите това, като погледнете стойността "scanAndOrder" на вашия objasni(), след като тествате заявката си. Ако тази стойност съществува и е вярна, това означава, че ще сортира набора от резултати в паметта (сканиране и подреждане), вместо да използва индекса директно. Това не може да бъде избегнато във вашия конкретен случай.
Следователно вашият индекс трябва да бъде :
db.posts.ensureIndex({start:1, end:1})
и вашата заявка (поръчката е променена само за яснота, оптимизаторът на заявки ще изпълни първоначалната ви заявка през същия път на изпълнение, но предпочитам да поставям индексираните полета на първо място и в ред) :
db.posts.find({start: {$lt: today}, end: {$gt: today}, status: {$gte:0}}).sort({sortOrder:1})