Медленный агрегат Монго при использовании $sort и $limit в $facet

Я заметил огромные различия в производительности в том, что кажется одинаковым, по крайней мере, концептуально. Тесты были выполнены на простой структуре коллекции, которая имеет _id, имя и созданный At, но их там 20 миллионов. Есть указатель на созданный Ат. Он размещен на кластере mlab, версия 3.6.9 WiredTiger.

Я пытаюсь запустить простой пейджинг с использованием агрегата, я знаю, что могу использовать find и limit, но мне нравится добавлять больше элементов в конвейер, пример, который я привожу, очень искажен.

db.getCollection("runnablecalls").aggregate([
         {
          $facet: {
            docs: [
                { $sort:  {createdAt: -1} },
                { $limit:  25 },
                { $skip:  0 },                                
            ],
            page_info: [
              { $group: { _id: null, total: { $sum: 1 } } 
              }
            ],
          }
        }                           
      ])

Это занимает почти 40s, Теперь, если я переехал $sort а также $limit за гранью требуется 0.042s,

db.getCollection("runnablecalls").aggregate([
        { $sort:  {createdAt: -1} },
        { $limit:  25 }, 
        {
          $facet: {
            docs: [           
                { $skip:  0 },                
            ],            
            page_info: [
                { 
                  $group: { _id: null, total: { $sum: 1 } } 
                } 
            ]}
        },                           
      ])

page_info Фасет не имеет значения в конце, я могу вынуть его без разницы, я просто оставляю это, потому что мне нравится использовать его. Я знаю, как решить проблему, используя два запроса: счетчик и агрегат без $facet, Мне просто нравится понимать, почему это происходит.

1 ответ

Первая агрегация не использует индекс. Второе объединение использует индекс и фильтрует первые 25 документов, прежде чем оно входит $facet, Можете добавить explain('executionStats') чтобы увидеть планы запросов и использование индексов. Например,

db.getCollection("runnablecalls").explain('executionStats').aggregate([
         {
          $facet: {
            docs: [
                { $sort:  {createdAt: -1} },
                { $limit:  25 },
                { $skip:  0 },                                
            ],
            page_info: [
              { $group: { _id: null, total: { $sum: 1 } } 
              }
            ],
          }
        }                           
      ])
Другие вопросы по тегам