Обновление Mongodb / поиск запроса с использованием неправильного индекса

#mongodb

#mongodb

Вопрос:

Мы переместили серверы БД, где новый сервер технически быстрее и имеет больший SSD, оперативную память и процессор. он имеет ту же версию mongodb 2.6. но мой запрос на обновление выполняется медленнее, чем должен быть. СТАРАЯ БД: 0,225 с, новая БД: 0,3 с — 1,5 с. так что это нестабильно.

 Update Query ($upsert: true):
{
        "_id.date" : "2016-10-03",
        "_id.week" : "Monday",
        "_id.hour" : "19",
        "_id.s_id" : "xxxx",
        "_id.c_id" : "yyyy",
        "_id.domain" : "pldt.com",
        "_id.l_id" : "zzzzz",
        "_id.o_id" : [ 
            {
                "or_id" : "wwww"
            }, 
            {
                "o_id" : "rrrrrr"
            }
        ],
        "_id.browser" : "Chrome",
        "_id.platform" : "Android",
        "_id.isp" : "PLDT",
        "_id.org" : "PLDT",
        "_id.country" : "China",
        "_id.city" : "",
        "_id.n_id" : NumberLong(5),
        "_id.device_type" : "mobile",
        "_id.cd" : "0",
        "_id.t_a_id" : "423525",
        "_id.c1" : "1",
        "_id.c2" : "2",
        "_id.c3" : "3",
        "_id.c4" : "4",
        "_id.set" : "1",
        "_id.device_name" : "Samsung Galaxy Note 4"
    }
  

Для этого у меня есть составной индекс. но, похоже, он его не использует.

 {
        "v" : 1,
        "key" : {
            "_id.date" : 1.0000000000000000,
            "_id.week" : 1.0000000000000000,
            "_id.hour" : 1.0000000000000000,
            "_id.s_id" : 1.0000000000000000,
            "_id.c_id" : 1.0000000000000000,
            "_id.domain" : 1.0000000000000000,
            "_id.l_id" : 1.0000000000000000,
            "_id.o_id" : 1.0000000000000000,
            "_id.browser" : 1.0000000000000000,
            "_id.platform" : 1.0000000000000000,
            "_id.isp" : 1.0000000000000000,
            "_id.org" : 1.0000000000000000,
            "_id.country" : 1.0000000000000000,
            "_id.city" : 1.0000000000000000,
            "_id.n_id" : 1.0000000000000000,
            "_id.device_type" : 1.0000000000000000,
            "_id.cloaked" : 1.0000000000000000,
            "_id.t_a_id" : 1.0000000000000000,
            "_id.c1" : 1.0000000000000000,
            "_id.c2" : 1.0000000000000000,
            "_id.c3" : 1.0000000000000000,
            "_id.c4" : 1.0000000000000000,
            "_id.set" : 1.0000000000000000,
            "_id.device_name" : 1.0000000000000000
        },
    "name" : "upsert_20160804",
    "ns" : "test2.map_collections1",
    "background" : true
}
  

У меня также есть несколько составных индексов. и когда я запускаю explain(), он использует другой индекс.

 /* 1 */
{
    "cursor" : "BtreeCursor _id.date_1__id.c_id_1",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 29789,
    "nscanned" : 29789,
    "nscannedObjectsAllPlans" : 134802,
    "nscannedAllPlans" : 148948,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 1163,
    "nChunkSkips" : 0,
    "millis" : 527,
    "indexBounds" : {
        "_id.date" : [ 
            [ 
                "2016-10-03", 
                "2016-10-03"
            ]
        ],
        "_id.c_id" : [ 
            [ 
                "yyyy", 
                "yyyy"
            ]
        ]
    },
    "server" : "mongo:27017",
    "filterSet" : false,
    "stats" : {
        "type" : "KEEP_MUTATIONS",
        "works" : 29791,
        "yields" : 1163,
        "unyields" : 1163,
        "invalidates" : 0,
        "advanced" : 1,
        "needTime" : 29788,
        "needFetch" : 0,
        "isEOF" : 1,
        "children" : [ 
            {
                "type" : "FETCH",
                "works" : 29790,
                "yields" : 1163,
                "unyields" : 1163,
                "invalidates" : 0,
                "advanced" : 1,
                "needTime" : 29788,
                "needFetch" : 0,
                "isEOF" : 1,
                "alreadyHasObj" : 0,
                "forcedFetches" : 0,
                "matchTested" : 1,
                "children" : [ 
                    {
                        "type" : "IXSCAN",
                        "works" : 29790,
                        "yields" : 1163,
                        "unyields" : 1163,
                        "invalidates" : 0,
                        "advanced" : 29789,
                        "needTime" : 0,
                        "needFetch" : 0,
                        "isEOF" : 1,
                        "keyPattern" : "{ _id.date: 1, _id.c_id: 1 }",
                        "isMultiKey" : 0,
                        "boundsVerbose" : "field #0['_id.date']: ["2016-10-03", "2016-10-03"], field #1['_id.c_id']: ["yyyy", "yyyy"]",
                        "yieldMovedCursor" : 0,
                        "dupsTested" : 0,
                        "dupsDropped" : 0,
                        "seenInvalidated" : 0,
                        "matchTested" : 0,
                        "keysExamined" : 29789,
                        "children" : []
                    }
                ]
            }
        ]
    }
}
  

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

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

1. Это один массивный _id объект и составной индекс. Вам действительно нужны все эти поля, чтобы однозначно идентифицировать ваши документы?

2. да, это для целей сокращения карты. В 1 документе может быть 1 тыс. поэтому он сохраняет его в $value.