Не совсем понятно, но я думаю, что вопрос в том, перевесят ли недостатки создания индекса в часто обновляемом поле преимущества быстрых запросов и сортировки в этом поле. Вы также подразумеваете, что ваш запрос будет фильтроваться по другому полю, а затем вы хотите отсортировать по этому полю. Не стесняйтесь уточнять ваш конкретный вариант использования.
Я думаю, что вы хотите что-то вроде этого:
db.test.save({filter: "stuff", count: "1"});
db.test.save({filter: "stuff", count: "3"});
db.test.save({filter: "stuff", count: "2"});
db.test.save({filter: "notstuff", count: "2"});
db.test.save({filter: "notstuff", count: "2"});
А потом вот такой индекс:
db.test.ensureIndex({filter:1, count:1});
А потом запрос вот так:
* * 1010
Который использует btree:
db.test.find({filter:"stuff"}).sort({count:1}).explain();
{
"cursor" : "BtreeCursor filter_1_count_1",
"nscanned" : 3,
"nscannedObjects" : 3,
...
Теперь, это действительно может зависеть от того, сколько результатов вам нужно вернуть. Если результатов всего несколько, вы можете отсортировать поля без индекса, что повысит производительность обновления. Я думаю, что на самом деле я сделаю несколько тестов, так как мне любопытно. Я обновлюсь немного.
update Я написал этот тест, чтобы показать разницу между сортировкой по индексу и без, и обновлением поля счетчика по индексу, и нет. Полный код здесь: https://gist.github.com/1696041
Он вставляет 700K и 7M документов (чтобы получить некоторое разнообразие), разделенных на 7 "фильтров". Затем он случайным образом выбирает документ, чтобы увеличить счет в 1M раз. Документы 1М на фильтр слишком велики, чтобы их можно было сортировать без ограничений, поэтому единственный способ показать, как работает этот фрагмент, - это ввести ограничение.
Вывод, как и ожидалось. Обновление поля счетчика занимает больше времени (почти вдвое дольше в этом тесте - но вдвое дольше, но все же довольно быстро), когда на нем есть индекс. Но гораздо быстрее делать запросы. Вы должны решить, что для вас важнее.
Вывод здесь (работает на моем MacBook Pro с SSD):
> bench();
benchmarking with index on {filter,data}, 700K docs
initialInsert of 700000 done in: 58304ms, 0.08329142857142857ms per insert
updateCounts 1000000 times done in: 103915ms, 0.103915ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 100000
scanAndOrder: true
millis: 1235
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 100000
scanAndOrder: true
millis: 614
benchmarking with index on {filter,data} and {filter, count}, 700k docs
initialInsert of 700000 done in: 72108ms, 0.10301142857142857ms per insert
updateCounts 1000000 times done in: 202778ms, 0.202778ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100000
scanAndOrder: undefined
millis: 139
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100
scanAndOrder: undefined
millis: 0
benchmarking with index on {filter,data}, 7M docs
initialInsert of 7000000 done in: 616701ms, 0.08810014285714286ms per insert
updateCounts 1000000 times done in: 134655ms, 0.134655ms per update
explain find({filter:"abcd"}).sort({count:-1}):
***too big to sort without limit!***
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_data_1
nscanned: 1000000
scanAndOrder: true
millis: 6396
benchmarking with index on {filter,data} and {filter, count}, 7M docs
initialInsert of 7000000 done in: 891556ms, 0.12736514285714284ms per insert
updateCounts 1000000 times done in: 280885ms, 0.280885ms per update
explain find({filter:"abcd"}).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 1000000
scanAndOrder: undefined
millis: 1337
explain find({filter:"abcd"}).limit(100).sort({count:-1}):
cursor: BtreeCursor filter_1_count_-1
nscanned: 100
scanAndOrder: undefined
millis: 0