Вы можете уменьшить проблемы производительности NTFS, разбив идентификатор GUID объекта на части и используя их в качестве имен каталогов. Таким образом, каждый каталог будет содержать только ограниченное количество подкаталогов или файлов.
например, если идентификатор будет aaaa-bb-cc-ddddeeee
, путь к элементу будет c: \ store \ aaaa \ bbcc \ dddd \ eeee.dat
, ограничивая каждый каталог не более чем 64 КБ подэлементов.
Вам нужно вызвать функцию prepare только один раз для каждого оператора, с параметром, обозначенным, например, ?
(поэтому ВЫБРАТЬ данные ИЗ хранилища WHERE id =?
- это инструкция, которую вы подготовили); тогда то, что вы делаете «миллионы раз», - это просто привязать параметр к подготовленному оператору и вызвать sqlite_step
- это быстрые операции. Стоит провести сравнительный анализ, если blob open может быть не быстрее. IOW, я рекомендую придерживаться SQLite и копаться в его низкоуровневом интерфейсе (из управляемого C ++, если необходимо) для максимальной производительности - это действительно потрясающий маленький движок, и он часто приятно удивлял меня своей производительностью!
Я думаю, что запрос к базе данных - ваш лучший выбор.
Вся структура базы данных настроена именно на такой случай, а синтаксический анализ и оптимизация простого запроса крайне несущественны.
Вы могли бы придумать схему, в которой вы храните все объекты в большом двоичном объекте непосредственно в файловую систему, а затем откройте для нее представление файла с отображением памяти и проиндексируйте идентификаторы объектов со смещением в большой двоичный объект, но я сомневаюсь, что вы увидите намного больше производительности, чем БД, поскольку это, по сути, то, что она делает.
Как насчет двоичного файла с блоками фиксированного размера около 2 КБ, где первые 4 байта являются длиной объекта ...
местоположение объекта i находится в i * 2048 байтов , затем считайте 2048 байт для объекта, получая длину фактического объекта из первых 4 байтов (без знака).
Рассматривали ли вы возможность попробовать объектную базу данных, например db4o ? Он может сохранить любой объект CLR и быстро получить к нему доступ с помощью языка запросов (поддерживает LINQ!). У меня не было миллионов объектов, но с несколькими тысячами доступ был довольно быстрым, без существенной разницы, чем аналогичный запрос SQL с индексированным полем идентификатора.
Сохранить отдельный индекс (другой файл) [Guid -> номер файла + смещение в файле]. Используйте двоичный поиск для поиска и переходите к файлу n + 1, когда файл n достигает определенного размера. Каждая строка в индексном файле составляет всего 24 байта (фиксированный размер: guid + номер файла + смещение, разделение файлов на 4 ГБ), и сортировка выполняется быстро (сортировка вставкой с низкой скоростью).
Изменить: у вас очень просто требования, которые легко оптимизировать. Эта тщательно построенная система должна превзойти базу данных, особенно если вы внимательно относитесь к чтению блоков данных и асинхронному вводу-выводу. Запросы к базе данных всегда будут связаны с накладными расходами на синтаксический анализ.
Редактировать 2: Если вам это нужно и безопасно (всегда хорошая идея), посмотрите здесь описание того, как концепция транзакций файловой системы может помочь вам в пуленепробиваемых вещах.
Мне нравится решение Эрвикера. То, как я поступил с этим, очень похоже.
Я сделал следующее:
Допустим, ваш идентификатор - 3F2504E0-4F89-11D3-9A0C-0305E82C3301.
Хеш-код guid до трех букв хэш. aaa-zzz.
Предположим, в качестве аргумента, что ваш guid хэширует до "xap".
Ваша информация будет найдена в файле c: \ store \ x \ xa \ xap \ 3F2504E04F8911D39A0C0305E82C3301.dat
Естественно, существует множество вариантов этой стратегии. Например, xap может быть файлом со всеми добавленными вместе двоичными объектами с заголовком или внешним файлом, содержащим в файле направляющие и смещения.
Я склонен согласиться с Алексом, если вы пишете свое собственное решение, вы изобретаете вещи, которые, скорее всего, уже есть в SQLite, но если вы должны ...
Вы, вероятно, можете создать BTree работать здесь. Это рабочая лошадка любой базы данных, и ваше проблемное пространство не так уж и плохо. Десятки миллионов объектов размером 1К - это всего лишь десятки миллиардов байтов, поэтому операционная система может управлять файлом, и есть много примеров BTree, которые можно попробовать.
По сравнению с использованием структуры каталогов файловой системы для создания файла Аналог BTree с использованием реального BTree будет намного быстрее.
Другое решение, которое может представлять интерес, - это Mogilfs , которая представляет собой распределенную резервную файловую систему.
Вы можете проверить, подходят ли структуры HDF5 для ваших задач
Я не знаю, поддерживает ли SQLite индексы или нет, но если да, то вы можете ускорить процесс, создав индекс над полем идентификатора.
Если нет, тогда ваш лучший вариант - деревья B +. Спасибо