Это может выглядеть как вопрос, подобный Оптимизация производительности для обработки 115 миллионов записей для вставки в Oracle , но я чувствую, что это другая проблема, и на другой вопрос нет однозначного ответа из-за некоторых отсутствие ясности.
Я загружаю файл netCDF, состоящий из следующих переменных и измерений, в три таблицы в базе данных для сбора данных из нескольких источников данных
Variables:
Time: 365 entries in hours since Jan 1, 1900
Latitude: 360 entries, center of 1/2 degree latitude bands
Longitude: 720 entries, center of 1/2 degree longitude bands
Precipitation: 3 Dimensional Array Time, Lat, Lon in dimensions
Три таблицы, которые я строю, выглядят так:
UpdateLog:
uid year updateTime
Location:
lid lat lon
(hidden MtM table) UpdateLog_Location:
uid lid
Precipitation:
pid lid uid month day amount
Если вы выполните математику, в Location (и скрытой таблице) будет около 250 тыс. Записей для каждого этого файла (это только год 2017), а в таблице Precipitation - до 94 млн. Записей.
Сейчас я просто использую Spring Boot, пытаюсь прочитать данные и обновить таблицы, начиная с Location.
Когда у меня размер пакета 1, база данных начала обновляться довольно быстро, но со временем зависла. В то время у меня не было настроено профилирование, поэтому я не был уверен, почему.
Когда я установил его на 500, я начал четко замечать шаги, поскольку он замедлял каждое обновление, но он начинался намного быстрее, чем размер пакета 1. 1. 1017 *
Я установил 250 000, и он обновил первые 250 000 записей примерно за 3 минуты, когда при размере партии в 1, 72 часа даже близко не подошли. Однако я начал профилировать программу и кое-что заметил. Похоже, что это проблема не с базой данных (35-40 секунд - все, что требуется для фиксации всех этих записей), а с Java, так как кажется, что Сборка мусора не поспевает за всеми старыми POJO.
Теперь я рассмотрел 2 возможных решения этой проблемы. Spring Batch, и просто прямой импорт CSV в MariaDB. Я бы предпочел сделать первое, если это возможно, чтобы сохранить единство, если это возможно. Однако я заметил, что Spring Batch также заставляет меня создавать POJO для каждого из элементов.
Решит ли Spring Batch эту проблему для меня? Можно ли это исправить с помощью диспетчера потоков и многопоточности операции, чтобы можно было запускать несколько ГХ одновременно? Или мне просто сделать прямой импорт файла CSV в MariaDB?
Проблема в том, что даже если я смогу сделать этот один файл за несколько дней, мы создадим базу данных с исторической погодой всех типов. Будет еще много файлов для импорта, и я хочу создать работоспособную структуру, которую мы можем использовать для каждого из них. Для этого единственного источника данных есть еще 116 лет данных!
Редактировать: Добавление некоторых показателей из прогона прошлой ночью, которые подтверждают мое убеждение, что проблема в сборке мусора.
194880 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
1165541217 nanoseconds spent preparing 518405 JDBC statements;
60891115221 nanoseconds spent executing 518403 JDBC statements;
2167044053 nanoseconds spent executing 2 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
6042527312343 nanoseconds spent executing 259203 flushes (flushing a total of 2301027603 entities and 4602055206 collections);
5673283917906 nanoseconds spent executing 259202 partial-flushes (flushing a total of 2300518401 entities and 2300518401 collections)
Как вы можете видеть, он тратит на 2 порядка больше времени на очистку памяти, чем на самом деле.