Запрос MongoDB занимает 2 минуты для сканирования 20 тысяч записей

#mongodb #performance #query-optimization

#mongodb #Производительность #оптимизация запроса

Вопрос:

Helo,

У меня есть коллекция mongodb, содержащая около 20 тысяч документов. Удаленные документы также сохраняются в коллекции, что означает, что они удаляются «мягко».

Теперь я хочу запросить документы на основе ключа «статус». Статус может быть либо «открыт», «закрыт», либо «удален». Мне нужны записи со статусом «закрыто»

Я вижу, что количество документов, удовлетворяющих моим критериям, составляет всего 25. Однако отсканированные документы (после применения индекса) составляют 18 тысяч.

Следовательно, выполнение моего запроса занимает около 2 минут, и часто время ожидания истекает.

Мои первые вопросы: 1. Должен ли запрос, выполняемый для 20 тысяч документов, занимать так много времени? 20 тыс. не такое уж большое количество, верно? 2. Может ли кто-нибудь помочь мне с дальнейшей оптимизацией запроса, если это возможно? Перенос удаленных записей в отдельную коллекцию архивов — последнее, что я хотел бы сделать.

Вот мой текущий запрос:

**

 db.collectionname.find({$and: [{ $and: [{ status: {$ne: 'open'} },{ status: {$ne: 'deleted'} }] }, 
							{ 'submittedDate': { $gte: new Date("2019-02-01T00:00:00.000Z"), $lte: new Date("2019-02-02T00:00:00.000Z") } }
						 ] })  

**

Ответ №1:

У вас должен быть индекс одного поля как {status: 1} . Замена индекса составным индексом {status: 1, submittedDate: 1} повысит вашу производительность. 20 тыс. ничего не значат при правильной индексации. Если у вас всего 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") }})
  

Комментарии:

1. Огромное спасибо. Добавление индекса «{status: 1, submittedDate: 1}» значительно помогло. Запрос теперь занимает всего 3 мс по сравнению с предыдущими 93 секундами.