Самый быстрый способ получать/хранить миллионы маленьких двоичных объектов

10 ответов

Вы можете уменьшить проблемы производительности NTFS, разбив идентификатор GUID объекта на части и используя их в качестве имен каталогов. Таким образом, каждый каталог будет содержать только ограниченное количество подкаталогов или файлов.

например, если идентификатор будет aaaa-bb-cc-ddddeeee , путь к элементу будет c: \ store \ aaaa \ bbcc \ dddd \ eeee.dat , ограничивая каждый каталог не более чем 64 КБ подэлементов.

10
ответ дан 9 December 2019 в 22:38
поделиться

Вам нужно вызвать функцию prepare только один раз для каждого оператора, с параметром, обозначенным, например, ? (поэтому ВЫБРАТЬ данные ИЗ хранилища WHERE id =? - это инструкция, которую вы подготовили); тогда то, что вы делаете «миллионы раз», - это просто привязать параметр к подготовленному оператору и вызвать sqlite_step - это быстрые операции. Стоит провести сравнительный анализ, если blob open может быть не быстрее. IOW, я рекомендую придерживаться SQLite и копаться в его низкоуровневом интерфейсе (из управляемого C ++, если необходимо) для максимальной производительности - это действительно потрясающий маленький движок, и он часто приятно удивлял меня своей производительностью!

1
ответ дан 9 December 2019 в 22:38
поделиться

Я думаю, что запрос к базе данных - ваш лучший выбор.

Вся структура базы данных настроена именно на такой случай, а синтаксический анализ и оптимизация простого запроса крайне несущественны.

Вы могли бы придумать схему, в которой вы храните все объекты в большом двоичном объекте непосредственно в файловую систему, а затем откройте для нее представление файла с отображением памяти и проиндексируйте идентификаторы объектов со смещением в большой двоичный объект, но я сомневаюсь, что вы увидите намного больше производительности, чем БД, поскольку это, по сути, то, что она делает.

0
ответ дан 9 December 2019 в 22:38
поделиться

Как насчет двоичного файла с блоками фиксированного размера около 2 КБ, где первые 4 байта являются длиной объекта ...

местоположение объекта i находится в i * 2048 байтов , затем считайте 2048 байт для объекта, получая длину фактического объекта из первых 4 байтов (без знака).

0
ответ дан 9 December 2019 в 22:38
поделиться

Рассматривали ли вы возможность попробовать объектную базу данных, например db4o ? Он может сохранить любой объект CLR и быстро получить к нему доступ с помощью языка запросов (поддерживает LINQ!). У меня не было миллионов объектов, но с несколькими тысячами доступ был довольно быстрым, без существенной разницы, чем аналогичный запрос SQL с индексированным полем идентификатора.

0
ответ дан 9 December 2019 в 22:38
поделиться

Сохранить отдельный индекс (другой файл) [Guid -> номер файла + смещение в файле]. Используйте двоичный поиск для поиска и переходите к файлу n + 1, когда файл n достигает определенного размера. Каждая строка в индексном файле составляет всего 24 байта (фиксированный размер: guid + номер файла + смещение, разделение файлов на 4 ГБ), и сортировка выполняется быстро (сортировка вставкой с низкой скоростью).

Изменить: у вас очень просто требования, которые легко оптимизировать. Эта тщательно построенная система должна превзойти базу данных, особенно если вы внимательно относитесь к чтению блоков данных и асинхронному вводу-выводу. Запросы к базе данных всегда будут связаны с накладными расходами на синтаксический анализ.

Редактировать 2: Если вам это нужно и безопасно (всегда хорошая идея), посмотрите здесь описание того, как концепция транзакций файловой системы может помочь вам в пуленепробиваемых вещах.

0
ответ дан 9 December 2019 в 22:38
поделиться

Мне нравится решение Эрвикера. То, как я поступил с этим, очень похоже.

Я сделал следующее:

Допустим, ваш идентификатор - 3F2504E0-4F89-11D3-9A0C-0305E82C3301.

Хеш-код guid до трех букв хэш. aaa-zzz.

Предположим, в качестве аргумента, что ваш guid хэширует до "xap".

Ваша информация будет найдена в файле c: \ store \ x \ xa \ xap \ 3F2504E04F8911D39A0C0305E82C3301.dat

Естественно, существует множество вариантов этой стратегии. Например, xap может быть файлом со всеми добавленными вместе двоичными объектами с заголовком или внешним файлом, содержащим в файле направляющие и смещения.

0
ответ дан 9 December 2019 в 22:38
поделиться

Я склонен согласиться с Алексом, если вы пишете свое собственное решение, вы изобретаете вещи, которые, скорее всего, уже есть в SQLite, но если вы должны ...

Вы, вероятно, можете создать BTree работать здесь. Это рабочая лошадка любой базы данных, и ваше проблемное пространство не так уж и плохо. Десятки миллионов объектов размером 1К - это всего лишь десятки миллиардов байтов, поэтому операционная система может управлять файлом, и есть много примеров BTree, которые можно попробовать.

По сравнению с использованием структуры каталогов файловой системы для создания файла Аналог BTree с использованием реального BTree будет намного быстрее.

Другое решение, которое может представлять интерес, - это Mogilfs , которая представляет собой распределенную резервную файловую систему.

0
ответ дан 9 December 2019 в 22:38
поделиться

Вы можете проверить, подходят ли структуры HDF5 для ваших задач

0
ответ дан 9 December 2019 в 22:38
поделиться

Я не знаю, поддерживает ли SQLite индексы или нет, но если да, то вы можете ускорить процесс, создав индекс над полем идентификатора.

Если нет, тогда ваш лучший вариант - деревья B +. Спасибо

0
ответ дан 9 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: