Обработка больших файлов асинхронная и дБ оптимизация - PullRequest
0 голосов
/ 05 января 2019

Мы должны получать ежечасно (диапазон 3 часа) наш ежедневный отчет (диапазон 24 часа), этот отчет будет содержать Запись соответствие (ссылка, id1, id2) с Транзакцией записей в нашем DB (ссылка, id1, id2), если совпадение найдено, мы должны включить эту запись в наше окончательное сравнение суммы в отчете и суммы вычисления количества совпадающих записей в нашей базе данных.
Мы используем JEE7, и пока мы придумали такой подход:
1. Анализировать / десериализовать потоковую передачу XML Ввести в объект Java с помощью Jackson
2. Как только пороговое значение 10K в оперативной памяти достигнет суммы / отфильтруйте эти объекты, а затем сериализуйте их в json, прежде чем временно сохранить их в БД.
3. Таким образом, к концу полного разбора мы будем фильтровать / суммировать и сериализовать в данные json нашу запись в дБ. Теперь мы начнем параллельное сравнение этих объектов Entry с нашей записью Transaction .

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

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

Ответы [ 2 ]

0 голосов
/ 09 января 2019

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

  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;

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

0 голосов
/ 09 января 2019

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

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

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

...