Медленный массив $ pu sh mongoDB запрос - PullRequest
0 голосов
/ 04 февраля 2020

У меня очень простая коллекция без индексов, кроме _id. Каждый документ содержит одно поле массива, mies. Текущий размер коллекции составляет около 100 миллионов, и я вижу следующие аномалии в профилировщике:

{
  "op": "update",
  "ns": "DB.links",
  "command": {
    "q": {
      "_id": "f1b54f37-7f92-4e75-9ec6-5329349ce792_eb370c8a-6f33-4989-aa59-a26e1c9df46c"
    },
    "u": {
      "$push": {
        "mies": {
          "$each": [
            {
              "$oid": "5e39d07bec34b8000e7f86b7"
            }
          ]
        }
      }
    },
    "multi": true,
    "upsert": true
  },
  "keysExamined": 0,
  "docsExamined": 0,
  "nMatched": 0,
  "nModified": 0,
  "upsert": true,
  "keysInserted": 1,
  "numYield": 0,
  "locks": {
    "Global": {
      "acquireCount": {
        "r": 2,
        "w": 2
      }
    },
    "Database": {
      "acquireCount": {
        "w": 2
      },
      "acquireWaitCount": {
        "w": 1
      },
      "timeAcquiringMicros": {
        "w": 19486143
      }
    },
    "Collection": {
      "acquireCount": {
        "w": 1
      }
    },
    "oplog": {
      "acquireCount": {
        "w": 1
      }
    }
  },
  "millis": 19490,
  "planSummary": "IDHACK",
  "execStats": {
    "stage": "UPDATE",
    "nReturned": 0,
    "executionTimeMillisEstimate": 0,
    "works": 2,
    "advanced": 0,
    "needTime": 1,
    "needYield": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "nMatched": 0,
    "nWouldModify": 0,
    "nInvalidateSkips": 0,
    "wouldInsert": true,
    "fastmodinsert": false,
    "inputStage": {
      "stage": "IDHACK",
      "nReturned": 0,
      "executionTimeMillisEstimate": 0,
      "works": 1,
      "advanced": 0,
      "needTime": 0,
      "needYield": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "keysExamined": 0,
      "docsExamined": 0
    }
  }
}

Как вы можете видеть, простой переход с одним $ pu sh к массиву занял 19 секунд. Я считаю, что большую часть времени здесь провели:

      "timeAcquiringMicros": {
        "w": 19486143
      }

Что мне проверить? Как я могу улучшить производительность?

1 Ответ

0 голосов
/ 05 февраля 2020

Вы не можете

MongoDB использует B-дерево алгоритм для индексации операций, таких как: вставка, поиск, удаление.

Algorithm   Average     Worst case
Space       O(n)        O(n)
Search      O(log n)    O(log n)
Insert      O(log n)    O(log n)
Delete      O(log n)    O(log n)

MongoDB необходимо детализировать упорядоченный индекс найти значение. Поскольку _id является уникальным индексом по умолчанию, MongoDB требуется итерация 27 для поиска документа в худшем случае (2 27 для 134.217.728 [~ 19сек], 2 28 для 268.435.456 [~ 21сек] и др. c ...)

Вы можете улучшить search операцию, создав compound index, но оштрафует insert, так как MongoDB необходимо обновить _id индекс + cound index.

...