Я пытаюсь прочитать данные, которые генерируются другим приложением и хранятся в файле .MDB Microsoft Office Access. Количество записей в некоторых конкретных таблицах может варьироваться от нескольких тысяч до более 10 миллионов в зависимости от размера модели (в другом приложении). Открытие всей таблицы в одном запросе может вызвать исключение из памяти в больших файлах. Поэтому я разбил таблицу на некоторые критерии и прочитал каждую часть в другом запросе. Но проблема в том, что файлы среднего размера можно читать значительно быстрее в одном запросе без каких-либо исключений.Как предотвратить исключение OutOfMemory при открытии больших файлов доступа .MDB?
Итак, я на правильном пути? Могу ли я решить проблему OutOfMemory по-другому? Можно ли выбрать одну из упомянутых стратегий (1 запрос или запрос N) в зависимости от количества записей?
Кстати, я использую стандартные компоненты ADO DelphiXE5 и Delphi. И мне нужны все данные таблицы, и не требуется присоединение к другим таблицам. Я создаю компоненты ADO по коду, и они не подключены к каким-либо визуальным средствам управления.
Edit:
Ну, кажется, что мой вопрос не достаточно ясно. Вот несколько подробностей, которые на самом деле отвечают на вопросы или предложения, высказанные в комментариях:
Этот файл .mdb не содержит настоящую базу данных; это просто структурированные данные, поэтому не записывать новые данные, никаких транзакций, не взаимодействовать с пользователем, ни сервера, ни ничего. Стороннее приложение использует файлы Access для экспорта результатов расчета. Общий размер этих файлов обычно составляет несколько сотен МБ, но они могут вырасти до 2 ГБ. Теперь мне нужно загрузить эти данные в структуру данных Delphi, прежде чем начинать мои собственные вычисления, так как нет необходимости ждать ввода-вывода во время этих вычислений.
Я не могу скомпилировать этот проект для x64, он чрезвычайно зависит от некоторых старых DLL, которые используют один и тот же менеджер памяти с основным исполняемым файлом, и их авторы никогда не выпустят версию x64. Компания еще не решила их заменить, и это не изменится в ближайшем будущем.
И, вы знаете, парни поддержки предпочитают говорить нам «исправить это», а не просить двух тысяч клиентов «купить больше памяти». Поэтому я должен быть очень скупым в использовании памяти.
Теперь мой вопрос: TADODataSet
обеспечивает лучшее управление памятью для сбора такого количества данных? Есть ли какое-либо свойство, которое не позволяет DataSet извлекать все данные одновременно?
Когда я звоню ADOTable1.open
, он начинает выделять память и ждет, чтобы получить всю таблицу, как и ожидалось. Но чтение всех этих записей в цикле for займет некоторое время, и нет необходимости иметь все эти данные, с другой стороны, нет необходимости хранить запись в памяти после ее прочтения, так как нет поиска в строках. Вот почему я разбил таблицу с некоторыми запросами. Теперь я хочу знать, может ли TADODataSet
справиться с этим или что я делаю, это единственное решение.
Всякий раз, когда кому-то нужна вся таблица, полная данных, это обычно проблема дизайна: вы должны серьезно задать вопрос, что «нужно», а не тратить свое время на технические проблемы, связанные с этими большими размерами таблиц. –
Данные представляют собой результаты анализа, созданные сторонним приложением, а файл .mdb - это просто хранилище, которое оно предлагает для передачи результатов. Здесь мне нужны все данные для дальнейших математических вычислений, и мне нужно это в ОЗУ вместо HDD. Какой дизайн вы предлагаете @JanDoggen? – saastn
Это будет зависеть от ваших математических вычислений. Но тогда это становится скорее вопросом статистического или количественного анализа, а затем вопросом программирования. Возможно, вы действительно не можете сломать свой набор данных, мы не можем это видеть. Мои замечания пришли больше из бизнес-приложений, где это часто случается. –