MongoDB [Index Optimization] производительность на этапе агрегации - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть около 50 M документа в моей базе данных Mongo с именем dma, и я использую это объединение для получения необходимых данных res, а затем манипулирую ими.

async function FormContract(ownerRealm, id) {
    try {
        const res = await collection.aggregate([
        {
            $match: {
                date: {$gt:moment.utc().subtract(1, 'days').toDate(), $lt:moment.utc().toDate()},
                id: id, //45 values one by one
                ownerRealm: {$in: ownerRealm} //20 values one-by-one
            }
        },
        {
            $group: {
                _id: "$lastModified",
                open_interest: {$sum: "$buyout"},
                min: {$min: "$price"},
                min_size: {$min: {$cond: [{$gte: ["$quantity", 200]}, "$price", "$min:$price"]}},
                avg: {$avg: "$price"},
                max: {$max: "$price"},
                max_size: {$max: {$cond: [{$gte: ["$quantity", 200]}, "$price", "$max:$price"]}},
                stdDevPop: {$stdDevPop: "$price"},
                cp: {$addToSet: "$owner"},
            }
        }]).exec();...

Схема моей коллекции выглядит так:

auc: { type: String },
id: { type: Number },
owner: { type: String },
ownerRealm: { type: String }, //20 unique values
bid: { type: Number },
buyout: { type: Number },
price: { type: Number },
quantity: { type: Number},
timeLeft: { type: String },
lastModified: { type: Number }, 
date: { type: Date, required: true } 

На данный момент есть пара слов о моей проблеме. У меня ~ 15 M документов, покрытых этим $match запросом date: {$gt:moment.utc().subtract(1, 'days').toDate(), $lt:moment.utc().toDate()},

Просто чтобы быть уверенным, мне нужны были только новые документы на последний день, поэтому, очевидно, они будут вставлены в конец коллекции

А затем мне нужно сделать 20 (realms) x 45 (id) aggregation запросов после него. Моя функция работает нормально, но в конечном итоге она выполняется .. эм долго.

Помните, я не говорю, что это медленно!

Вариант использования:

  • Если я использую for (ownerRealms.length) внутри for(id.length)

    for (let i = 0; i < ownerRealms.length; i++) {
        for (let j = 0; j < id.length; j++) {
            FormContract(ownerRealm, id)
    

    что 20 servers x 45 id = 900 запросы будут формировать необходимые данные один по одному без высокой нагрузки на процессор и оперативную память в течение ~ 20 минут для каждого сервер или 20 mins x 20 servers = 400 mins или ~ 6 ЧАСОВ!

  • или если я использую for(id.length) и map(servers)

    for (let j = 0; j < id.length; j++) {
        const data = await Promise.all(ownerRealms.map(async ({ ... }) => {
             FormContract(ownerRealm, id)
    

    это было бы асинхронно 20 $aggregation запросов по одному 45 раз. Или 1 час на 10 идентификаторов или ~ 4,5 часа ( гораздо лучше, верно? ), но это создает большую нагрузку на Процессор (почти все ядра при загрузке 90%, больной)

Я работаю на машине с 7 ядрами, 7 ГБ ОЗУ и 80'000 + IOPS SSD, так что, думаю, я делаю что-то не так, если я принимаю 90% загрузки процессора в течение 4,5 часов

Так есть ли идеи, что будет лучше для оптимизации? Прежде всего я создаю индекс в этой коллекции, и он выглядит так:

lastModified:-1
ownerRealm:1
date:-1
id:-1

Но, согласно Mongo Compass, он используется 0 раз и хранится в отдельной коллекции БД под названием undefinded. Рис здесь:

enter image description here

Так в чем проблема? Я ошибаюсь? Должен ли я создать лучший индекс. Или есть другой способ, который я упускаю, например, хранение данных на этапе $match где-то еще? Или использовать $sort stage? Я прочитал, что запрос $match должен быть первым, потому что он вызывает всю коллекцию.

Я уже проверял это StOv вопросы: Оптимизация индекса для структуры агрегации mongodb и Повышение производительности MongoDB с помощью сортировки и уже проверка dba.stackexchange на что-то полезное .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...