Асинхронная обработка больших файлов и оптимизация БД

Мы должны получать ежечасно (3-часовой диапазон) наш ежедневный отчет (24-часовой диапазон), этот отчет будет содержать сопоставление Вход (ссылка, id1, id2) с записями Сделка в нашей базе данных (ссылка, id1, id2), если совпадение найдено, нам нужно чтобы включить эту запись в наше окончательное сравнение суммы в отчете и суммы расчета совпадающей суммы записи в нашем DB.
Мы используем JEE7 и до сих пор придумали такой подход:
1. Разобрать / де-сериализовать потоковую передачу xml Вход в объект Java с помощью Jackson
2. Как только порог памяти в 10 КБ достигает объекта, суммируйте / отфильтруйте эти объекты, а затем сериализуйте их в json перед их временным сохранением в DB.
. 3. Итак, к концу полного анализа мы отфильтруем / суммируем и сериализуем в данные json наш Вход в db. С этого момента мы начнем параллельно, чтобы сравнить эти объекты Вход с нашей записью Сделка.

Здесь я хочу некоторой оптимизации, потому что все, что мы хотим, - это сравнить эти Запись (ссылка, id1, id2) = транзакция (ссылка, id1, id2), и если совпадение найдено, мы учитываем эту транзакцию в нашем окончательном расчете, потому что она была частью нашего отчета. Таким образом, практически все (ссылка, id1, id2) должны быть уникальными. Я читаю о функции ora_hash или индексе нескольких столбцов, чтобы ускорить этот поиск. Тогда есть некоторое ограничение с предложением SQL IN (1000 записей), см. здесь
Мы также используем метод Ejb Async для достижения этого параллелизма, и нам все еще нужно работать над тем, чтобы узнать, когда этот асинхронный вызов заканчивается, не нужно вводить задержку потока.

Я хочу знать несколько оптимизаций в этом подходе, и в целом, если этот подход подходит после того, как мы помечаем всю нашу транзакцию на RHS, мы делаем, поскольку шаг 4 заключается в запросе и суммировании всех этих сумм и сопоставлении с той, которая была предоставлена ​​в этом отчете, на этом делается вывод. наш процесс.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
270
2

Ответы 2

Здесь вы делаете слишком много промежуточных шагов. Если вы блокируете ввод-вывод в базе данных, вы можете использовать шаблон Pub / Sub (через метод Ejb Async), чтобы поддерживать базу данных на максимальном уровне, но я бы сначала протестировал с одним потоком. Вы, скорее всего, переполните свой ввод-вывод и все равно будете заблокированы.

Если вы уже десериализовались (из XML), почему бы вам просто не записать ссылку, id1 и id2 в локальную таблицу, а затем присоединить ее к таблице транзакций для вашего отчета? Почему вы проходите все эти промежуточные этапы (JSON?) Не пытайтесь превзойти базу данных, когда дело доходит до сравнения больших объемов данных, это будет лучше, чем у вас.

Честно говоря, в зависимости от вашей RDMS вы можете решить это совершенно неверным способом. Большинство решений RDMS имеют возможность напрямую анализировать XML-файл:

Типичный подход в такой ситуации:

  1. Загрузите данные из файла в промежуточную таблицу

  2. Запустите отчет по базе данных (включая промежуточную таблицу)

Загрузка данных

Промежуточная таблица должна иметь три столбца ссылка, id1 и id2 и соответствующие индексы для эффективного соединения с таблицей Сделка.

Вы можете эффективно загружать XML-данные с помощью Oracle SQL * Loader. Но поскольку у вас уже есть много кода Java для него, вы также можете загрузить его с помощью Java и JDBC. Для максимальной производительности используйте Пакетная обработка JDBC.

Запустить отчет

Когда вы запускаете отчет, присоединитесь к промежуточной таблице, например:

SELECT SUM(amount)
FROM Transaction t
JOIN Staging s on t.reference = t.reference
    AND t.id1 = s.id1 AND t.id2 = s.id2;

Скорее всего, в этой настройке нет необходимости в параллелизме. Он просто использует тот факт, что системы реляционных баз данных эффективны при обработке больших блоков данных (в отличие от записи за записью).

Другие вопросы по теме