Лучшие практики для загрузки очень больших наборов данных в реляционную базу данных через Java - PullRequest
0 голосов
/ 12 мая 2018

Хотя в прошлом я работал с большими наборами данных, никогда с такими огромными.Вот разбивка:

  • Каждый месяц я буду получать плоский файл объемом 5 ГБ, содержащий 1 запись базы данных на строку
  • Этот файл содержит приблизительно 10 миллионов строк данных, причем каждый последующий месяц содержит большеданные, чем предыдущие
  • В данных могут быть точные дубликаты, которые необходимо игнорировать
  • В данных также могут быть неточные дубликаты, которые необходимо проанализировать и вставить только одну из строкостальные отбрасываются

Мне нужно настроить начальную загрузку данных за 10 лет, что составляет приблизительно 1,5 миллиарда строк.У меня нет проблем с обработкой базы данных, но у меня возникают трудности с быстрой загрузкой этих данных.

В настоящее время я вставляю строки по одной за раз, что позволяет ограничениям первичного ключа сообщать мне, если у меня есть строкачто нужно пересмотреть, те идут в отдельной таблице.

Загрузка файла объемом 5 ГБ занимает около 10 часов, и это самый быстрый способ получить его.У меня настроена предварительная обработка около 25 000 строк за раз, затем я перебираю их с помощью одного оператора, например, так:

public void saveBatchSql(String[] sql) {
    try {
        Statement stmt = dbCon.createStatement();

        for (String query : sql) {
            try {
                stmt.execute(query);
            }
            catch (Exception ee) {
                query = query.replace("component_detail", "component_detail_duplicate");
                stmt.execute(query);
            }
        }

        stmt.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }

}

Пока что это лучшее, что я могу прийтис.У кого-нибудь есть идеи о том, как я могу заставить это работать быстрее?Насколько я могу судить, я не могу обработать все записи в памяти, но, может быть, есть какой-то другой способ?

Кстати, база данных, в которую я загружаю, - это Sybase версии 16.

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Предполагая, что вы говорите о Sybase ASE 16, поработайте с вашим администратором базы данных, чтобы отслеживать свои нагрузки, чтобы увидеть, где у вас возникают узкие места.

Основной упор будет сделан на сбор / анализ данных MDA (master..mon%таблицы);Ключевыми элементами для поиска являются события ожидания / тайминги, а также производительность отдельных вставок (использование процессора / памяти, логические операции ввода-вывода и т. д.).

Выясните, нужно ли обновлять большое количество индексов.... или, возможно, запуск проверки RI / внешнего ключа ... или запуск триггеров ... все это может значительно снизить пропускную способность ваших вставок.


Некоторые общие идеи дизайна...

1) использовать подготовленные операторы (и убедитесь, что вы используете повторно подготовленный оператор вместо создания нового подготовленного оператора для каждой вставки) - цель состоит в том, чтобы исключить накладные расходы, связанные с компиляцией базы данных каждой инструкции вставки

2) пакетируйте ваши вставки (то есть, оберните в begin/commit tran) и проверьте, какой размер подходит вам лучше - цель состоит в том, чтобы сократить количество относительно медленных записей журнала, которые БД должна выполнитьдля каждой транзакции

3) поскольку чтение (из вашего файла), вероятно, происходит быстрее, чем запись (в базу данных), обратите внимание на то, как ваш поток чтения читается вПотоки нескольких / параллельных писателей - цель состоит в том, чтобы убедиться, что вы не ограничиваетесь при записи

4), чтобы разделить ваши чтения (при каждом считывателе, поступающем в несколько / параллельных писателей), например, иметь отдельные потоки чтения, читаемые из разныхфайлы данных

5), как уже упоминалось lexicore, посмотрите, можете ли вы использовать утилиту ASE bcp (на уровне ОС) для массовой загрузки данных

0 голосов
/ 12 мая 2018

Это зависит от базы данных, но обычно рекомендуется использовать инструменты базы данных для загрузки данных из некоторого простого формата, такого как CSV. В зависимости от базы данных вам может потребоваться удалить индексы до и заново создать их после импорта. Документация по базе данных часто содержит некоторые советы о том, как сделать массовую загрузку данных производительной.

Я бы не советовал использовать Java для массовой загрузки. Для чего?

Просто для загрузки? Инструменты базы данных оптимизированы для этого, вы не сможете сделать это лучше в Java.

Обработка данных при загрузке? Ну, обычно вы можете выполнять большую часть обработки данных с помощью SQL в базе данных. Поэтому загрузите данные во входящую таблицу и запустите к ней SQL-запросы. Это намного более гибко по сравнению с логикой обработки жесткого кода в Java. В большинстве случаев это также будет более эффективным, поскольку базы данных достаточно умны в отношении оптимизации запросов / операторов SQL.

...