Вы должны иметь один индекс поля как {status: 1}
. Замена индекса составным индексом {status: 1, submittedDate: 1}
улучшит вашу производительность. 20k - ничто, если правильно проиндексировано. Если у вас только 3 статуса, замените ваш запрос следующим образом.
db.collectionname.find({status: 'closed',
'submittedDate': { $gte: new Date("2019-02-01T00:00:00.000Z"),
$lte: new Date("2019-02-02T00:00:00.000Z") }})
Циклы не плохие, но их часто избегают, потому что они могут усложнить задачу, чтобы у вас не было утечек памяти. Утечки возникают, особенно когда объекты «подсчитываются». В языке или системе, где используется подсчет ссылок, объект отслеживает количество ссылок, указывающих на него. Каждый раз, когда ссылка удаляется, счетчик уменьшается, когда счетчик становится равным нулю, ссылок нет, и поэтому объект можно удалить.
Обычно это само собой решается и работает нормально, без тщательного обдумывания. Если у вас есть группа объектов без циклов, и вы отбрасываете свою ссылку на корневой объект, то она будет удалена, это означает, что ссылки, которые она имеет на принадлежащие ей объекты, будут удалены, а объекты, на которые ссылаются, будут иметь счетчики ссылок идти в ноль. Oни' Он будет удален, и каскад приведет к удалению всех объектов.
Но ... если у вас есть цикл, этот каскад не работает. У вас может быть группа объектов, и они вам больше не нужны, поэтому вы отбрасываете единственную ссылку, которая у вас есть на эти объекты, но поскольку цикл существует, объекты ссылаются друг на друга. Это означает, что их счетчики ссылок никогда не обнуляются, и они не удаляются. Это утечка памяти.
Очевидно, что вы можете сделать некоторое осторожное управление и разорвать циклы, прежде чем отбросить ссылку на группу объектов, которые вам больше не нужны. Но ... как я только что сказал, это требует тщательного управления. Очень легко ошибиться. Это одна из главных причин возникновения утечек памяти.
Чтобы избежать риска утечек и хитрой работы правильного прерывания циклов, когда вам больше не нужна группа объектов, программисты обычно стараются избегать циклов. Это становится более важным в больших проектах со многими программистами, где никто не понимает всю систему. Если бы были циклы, программистам пришлось бы следить и тратить много времени на изучение кода друг друга, чтобы избежать циклов.
Некоторые языки со сборщиками мусора (например, C #) могут удалять группу объектов, которые больше не нужны, даже если группа содержит циклы.
Цикл сохранения может быть прерван, если вы знаете об этом. Обычно это приводит к неприятным ошибкам (утечкам памяти). В вашем примере:
A* a = [[A alloc] initAndCreateB];
Теперь безымянный экземпляр B (созданный A) имеет счет сохранения 1. Так как мы храним ссылку на A, а анонимный экземпляр B содержит строгую ссылку на A, счет хранения A равен 2.
Скажем, мы закончили с использованием A:
[a release];
return 12;
Теперь, счет сохранения A равен 1. Он не будет освобожден, его память потеряна. Вот почему сохранять циклы плохо.
The way to break a retain loop is to have a separate "close" method.
i.e.
A retains B
B retains A
when you're done, call a method (I'll call it "close
") on A where A releases B. You can then release A and the whole loop will release (assuming there are no retains elsewhere).
Проблема заключается в следующем: A указывает и сохраняет B, а B указывает и сохраняет A. Когда нет других ссылок на A или B, не будет никакого способа освободить их, потому что ваше приложение не имеет ссылок на них на данный момент. Это называется ссылочным циклом, и это тип утечки памяти, распространенный в любой системе с подсчетом ссылок. Для решения этой проблемы в большинстве языков высокого уровня используется сборка мусора, а не подсчет ссылок.