Я знаю его старый пост, но для людей, которые ищут лучшие точки для написания операций с данными на языках программирования.
Я не уверен, рассмотрели ли вы, как инструменты ETL выполняют свои операции загрузки данных и воспроизводят похожую стратегию в вашем коде.
Одно из таких предложений - параллельные каналы передачи данных. Здесь каждый канал будет выполнять ETL для отдельных фрагментов на основе разделения данных из источника. Например, вы можете параллельно рассматривать процессы порождения для данных за разные недели. Это по-прежнему не решит проблемы с памятью в рамках одного процесса. Хотя может использоваться в случае, если вы достигнете предела с распределением памяти в куче в рамках одного процесса. Это также полезно для чтения данных параллельно с произвольным доступом. Хотя потребуется главный процесс для координации и завершения процесса как одной операции ETL.
Я предполагаю, что вы выполняете в преобразовании много операций поиска, прежде чем наконец записать свои данные в базу данных. Предполагая, что главная таблица транзакций огромна, а справочные данные малы. Вы должны сосредоточиться на работе структуры данных и логарифмирования. Ниже приведены несколько советов для того же. Изучите характеристики ваших данных перед тем, как выбрать наиболее подходящий для написания алгоритма.
Как правило, данные поиска (справочные данные) хранятся в кэше. Выберите простую структуру данных, которая эффективна для операций чтения и поиска (скажем, список массивов). Если возможно, отсортируйте этот массив по ключу, к которому вы присоединитесь, чтобы быть эффективным в вашем алгоритме поиска.
Существует различная стратегия для операций поиска в ваших задачах преобразования. В мире баз данных это можно назвать операцией соединения.
Алгоритм слияния:
Идеально, когда источник уже отсортирован по ключу атрибута соединения. Основная идея алгоритма сортировки-слияния состоит в том, чтобы сначала отсортировать отношения по атрибуту соединения, чтобы чередующиеся линейные сканы встретились с этими наборами одновременно. Для примера кода, https://en.wikipedia.org/wiki/Sort-merge_join
Nested Join:
работает как вложенный цикл, где каждое значение индекса внешнего цикла берется в качестве предела (или начальной точки, или чего-либо другого) для индекса внутреннего цикла, и соответствующие действия выполняются над оператором (ами) после внутренний цикл Таким образом, в основном, если внешний цикл выполняет R раз и для каждого такого выполнения внутренний цикл выполняет S раз, то общая стоимость или временная сложность вложенного цикла составляет O (RS).
Соединения с вложенными циклами обеспечивают эффективный доступ, когда таблицы индексируются по столбцам соединения. Кроме того, во многих небольших транзакциях, таких как транзакции, затрагивающие только небольшой набор строк, вложенные в индекс петлевые соединения намного превосходят как соединения sort -merge, так и соединения хэшей
Я описываю только два метода, которые можно использовать в вашей операции поиска. Основная идея, которую нужно запомнить в ETL, заключается в поиске и получении кортежей (как установлено) для дальнейшей работы. Поиск будет основываться на ключе, а результирующие ключи транзакции извлекут все записи (проекция). Возьмите это и загрузите строки из файла за одну операцию чтения. Это больше совет, если вам не нужны все записи для операций преобразования.
Другая очень дорогостоящая операция - обратная запись в базу данных. Может быть тенденция обрабатывать извлечение, преобразование и загрузку по одной строке за раз. Подумайте об операциях, которые можно векторизовать, где вы можете выполнить их вместе с операцией над структурой данных в натуральном выражении. Например, лямбада-операция над многомерным вектором, а не зацикливание каждой строки по одному и выполнение преобразования и операций по всем столбцам для данной строки. Затем мы можем записать этот вектор в файл или базу данных. Это позволит избежать давления памяти.