Теперь я использую Berkeley DB для создания Btree, хранящего 80 миллионов записей. Мне нужно вставить их, отсканировать и обновить их значения. Однако только обновление занимает около 1 часа, что для меня слишком медленно. В https://docs.oracle.com/cd/E17076_05/html/gsg/CXX/BerkeleyDB-Core-Cxx-GSG.pdf сказано, что каждая операция чтения в Berkeley DB загружает в память целую страницу. Интересно, есть ли способы этого избежать? То есть каждый раз, когда я хочу получить запись, в память будет загружаться только ее пара ключа и данных, а не вся страница, содержащая ее? Спасибо.
@MikeAndrews Спасибо, Майк. Мой ключ - это структура, состоящая из 3 беззнаковых int (я думаю, что это 12 байт). а для значения он включает беззнаковый int и указатель void (я думаю, 8 байтов, указатель всегда устанавливается в NULL для дальнейшего расширения). Страница BDB установлена на 4 КБ, размер блока ввода-вывода моего сервера. Есть ли у вас какие-либо мнения по поводу повышения эффективности? Спасибо.
@MikeAndrews Кстати, "подготовка индекса" фактически включает 1 вставку и 2 обновления. То есть он состоит из 3 шагов: (1) вставить все 80 миллионов записей в набор данных (2) сканировать с начала записи в индексе и обновлять их значения одну за другой (3) другое сканирование с начала и обновлять их значение по одному. Объем памяти ограничен всего 2 ГБ, поэтому я думаю, что сейчас операция ввода-вывода - это основная часть программы. И размер набора данных составляет 2 ГБ. После того, как все вставлено, файл .db составляет около 5 ГБ.
Вам нужно будет вызвать в свое приложение, но один из способов улучшить производительность записи - это уменьшить агрессивность базы данных. Если вам вообще не нужна атомарность, вы можете работать без транзакций. Если вам нужна атомарность, но вы можете терпеть несколько потерянных записей при восстановлении, попробуйте флаг DB_TXN_WRITE_NOSYNC или даже DB_TXN_NOSYNC (см. Этот ответ: stackoverflow.com/questions/3825022/…).
И здорово, что размер страницы соответствует размеру блочного ввода-вывода для вашего сервера! Я бы не стал этого менять. Если бы ваши записи были большими, и вы постоянно переполнялись, вы могли бы перейти к большему размеру страницы. Но размер 4K настолько мал, насколько вам хотелось бы, даже для очень маленьких ключей / данных, как у вас.
Другой вариант, хотя он и начинает немного терять смысл наличия такой базы данных, - это «складывать» ваши записи в более крупные логические записи. Если бы вы могли сгруппировать свои записи в ячейки по 64, относясь к BDB как к хеш-таблице, то вы бы сократили количество вставок с 80 миллионов до 1,25 миллиона. Для вашего приложения эта запись будет иметь размер около килобайта и при этом легко уместиться на странице.
@MikeAndrews Спасибо. Я не использовал DBenv. Поэтому считаю, что транзакций быть не должно. Является ли?
Ах, ну уж точно логов без окружения не бывает. Можно подумать, что это лучший вариант для Berkeley DB! (в стороне, убедитесь, что вы установили размер кеша с помощью DB-> set_cachesize ().) Но, если вы не используете транзакции или среду ... может быть, вам не нужна Berkeley DB? Я имею в виду, что вы жестяная банка заставляете BDB работать быстро, но вы потратите на это кучу своей жизненной энергии. Вы могли бы вместо этого оценить LMDB или другое современное хранилище ключей / значений?
@MikeAndrews En, мне очень жаль. Я не использовал DB-> set_cache, а размер по умолчанию для BDB составляет 256 КБ. Это имеет значение? Я не совсем понимаю его влияние.
Ах, да! Вы захотите установить его настолько большим, насколько сможете. Если у вас 2 ГБ ОЗУ, оставьте место для операционной системы и всего остального, что есть в системе. Если вы можете получить его выше 1 ГБ, ваша программа должна быть намного, намного счастливее.

Привет, Кайджи, добро пожаловать в Stack Overflow! Похоже, вы работаете на грани возможностей BDB, но это полностью зависит от размера ваших записей. При 80 миллионах записей в час у вас будет около 45 микросекунд на запись. Это может быть «неплохо», если ваши записи имеют размер в килобайтах. Какой диапазон размеров для ваших ключей и ваших данных? И какой у вас установлен размер страницы BDB? Вы обязательно должны прочитать всю конечную страницу и, возможно, несколько страниц индекса. Но вы можете изменить размер страницы, чтобы она лучше соответствовала вашим записям.