Подтвердить что ты не робот

Разница в производительности Mongodb между индексами хэша и восходящей (любая причина не использовать хеш в не упорядоченном поле?)

В mongodb существует несколько типов index. По этому вопросу меня интересует возрастающий (или убывающий) индекс, который можно использовать для сортировки, и хэш-индекс, который в соответствии с документацией "в основном используется с закрытыми кластерами для поддержки хешированных ключей осколка" (источник), обеспечивающий "более равномерное распределение данных" (источник)

Я знаю, что вы не можете создать индекс вроде: db.test.ensureIndex( { "key": "hashed", "sortOrder": 1 } ), потому что вы получите сообщение об ошибке

{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "errmsg" : "exception: Currently only single field hashed index supported.",
    "code" : 16763,
    "ok" : 0
}

Мой вопрос:

Между индексами:

  • db.test.ensureIndex( { "key": 1 } )

  • db.test.ensureIndex( { "key": "hashed" } )

Для запроса db.products.find( { key: "a" } ), который более эффективен?, это клавиша hashed O(1)


Как я попал на вопрос:

Прежде чем я узнал, что у вас не может быть многозначных индексов с hashed, я создал индекс формы db.test.ensureIndex( { "key": 1, "sortOrder": 1 } ), и, создав его, я задался вопросом, был ли хешированный индекс более результативным, чем восходящий (хеш обычно O(1)). Я оставил ключ, как сейчас, потому что (как я уже упоминал выше) db.test.ensureIndex( { "key": "hashed", "sortOrder": 1 } ) не разрешалось. Но вопрос о хэшированном индексе быстрее для поисков с помощью ключа остался в моем сознании.

Ситуация, в которой я сделал индекс, была:

У меня была коллекция, содержавшая отсортированный список документов, классифицированных ключами.

например. {key: a, sortOrder: 1, ...}, {key: a, sortOrder: 2, ...}, {key: a, sortOrder: 3, ...}, {key: b, sortOrder: 1, ...}, {key: b, sortOrder: 2, ...},...

Поскольку я использовал key для классификации и sortOrder для разбивки на страницы, я всегда запрашивал фильтрацию с одним значением для key и используя sortOrder для порядка документов.

Это означает, что у меня было два возможных запроса:

  • Для первой страницы db.products.find( { key: "a" } ).limit(10).sort({"sortOrder", 1})
  • И для других страниц db.products.find( { key: "a" , sortOrder: { $gt: 10 } } ).limit(10).sort({"sortOrder", 1})

В этом конкретном сценарии поиск с O(1) для ключа и O(log(n)) для sortOrder был бы идеальным, но это не было разрешено.

4b9b3361

Ответ 1

Для запроса db.products.find( { key: "a" } ), какой из них более эффективен?

Учитывая, что поле key индексируется в обоих случаях, сам поиск индекса сложности будет очень похож. Поскольку значение a будет hashed и сохранено в дереве индексов.

Если мы ищем высокую стоимость исполнения, хешированная версия повлечет за собой дополнительную (незначительную) стоимость хэширования значения a перед сопоставлением значения в дереве индексов. См. Также mongo/db/index/hash_access_method.h

Кроме того, хэшированный индекс не сможет использовать префикс префиксов индекса (WiredTiger). Сжатие префиксов префиксов особенно эффективно для некоторых наборов данных, таких как с низкой мощностью (например, страны) или с повторяющимися значениями, такими как номера телефонов, коды социального обеспечения и геокоординаты. Это особенно эффективно для составных индексов, где первое поле повторяется со всеми уникальными значениями второго поля.

Любая причина не использовать хеш в неупорядоченном поле?

Как правило, нет никакой причины для хеширования значения вне диапазона. Чтобы выбрать ключ осколка, рассмотрите мощность, frequency и скорость изменения значения.

Хешевый индекс обычно используется для конкретного случая sharding. Когда значение shard key является монотонно увеличивающим/уменьшающим значением, распределение данных, скорее всего, перейдет только в один осколок. Именно здесь хешированный осколочный ключ сможет улучшить распределение записей. Это небольшой компромисс, который значительно улучшит ваш осколочный кластер. См. Также Hashed vs Ranged Sharding.

стоит ли вставлять случайный хеш или значение в документ и использовать его для очертания вместо хэша, сгенерированного на _id?

Стоит ли это, зависит от варианта использования. Пользовательское хеш-значение будет означать, что любой запрос для хеш-значения должен пройти через пользовательский хеширующий код, то есть приложение.

Преимущество использования встроенной хеш-функции заключается в том, что MongoDB автоматически вычисляет хэши при разрешении запросов с использованием хешированных индексов. Поэтому приложениям не нужно вычислять хеши.