В настоящее время я играю с RocksDB (C ++) и мне было любопытно узнать о некоторых показателях производительности, с которыми я столкнулся.
В целях тестирования мои ключи базы данных являются путями к файлам, а значения - именами файлов. В моей базе данных около 2 миллионов записей. Я запускаю RocksDB локально на MacBook Pro 2016 (SSD).
В моем сценарии использования преобладает чтение. Полное сканирование ключа является довольно распространенным, как и сканирование ключа, которое включает «значительное» количество ключей. (50% +)
Мне любопытны следующие наблюдения:
1. Iterator
значительно быстрее, чем вызов Get
при выполнении полного сканирования ключей.
Когда я хочу просмотреть все ключи в базе данных, я вижу улучшение производительности в 4-8 раз при использовании Iterator
вместо вызова Get
для каждого ключа. Использование MultiGet
не имеет значения.
В случае вызова Get
примерно 2M раз ключи были предварительно извлечены в вектор и отсортированы лексикографически. Почему вызов Get
повторяется намного медленнее, чем использование Iterator
? Есть ли способ сократить разрыв в производительности между двумя API?
2. При извлечении примерно половины клавиш производительность между использованием Iterator
и Get
начинает становиться незначительной.
Поскольку количество ключей для выборки уменьшается, выполнение нескольких вызовов на Get
начинает занимать примерно столько же времени, сколько и Iterator
, поскольку итератор платит цену сканирования ключей, которых нет в желаемый набор ключей.
Есть ли какое-то "волшебное" соотношение, где это становится правдой для большинства баз данных? Например, если мне нужно отсканировать более 25% ключей, то вызов Get
будет быстрее, но если это 75% ключей, то Iterator
будет быстрее. Но эти цифры просто «составлены» грубым тестированием.
3. Выборка ключей в отсортированном порядке не улучшает производительность.
Если я предварительно отсортирую ключи, которые я хочу получить, в том же порядке, в котором Iterator
вернет их, это не вызовет многократный вызов Get
. Это почему? В документации упоминается, что рекомендуется сортировать ключи перед выполнением пакетной вставки. Разве Get
не извлекает выгоду из того же упреждающего кэширования, от которого Iterator
извлекает выгоду?
4. Какие настройки рекомендуются для случая интенсивного чтения?
Наконец, есть ли какие-то особые настройки, рекомендуемые для случая интенсивного чтения, который может включать сканирование значительного числа клавиш одновременно?
macOS 10.14.3, MacBook Pro 2016 SSD, RocksDB 5.18.3, Xcode 10.1