Я реализую особенность импорта данных приложения из одной базы данных в другую.
У меня есть файл CSV, содержащий, скажем, 10000 строк. Эти строки необходимо вставить / обновить в базе данных.
Возможен случай, когда в базе данных может присутствовать пара строк, что означает необходимость их обновления. Если они отсутствуют в базе данных, их необходимо вставить.
Одним из возможных решений является то, что я могу читать по одной строке, проверять записи в базе данных и строить запросы на вставку / обновление соответственно. Но этот процесс может занять много времени для создания запросов на обновление / вставку и выполнения их в базе данных. Иногда мой CSV-файл может содержать миллионы записей.
Есть ли другой быстрый способ добиться этой функции?
OutOfMemory
!Ответы:
В Oracle есть хорошая технология, которая называется External Tables. В вашем сценарии вы можете получить доступ к своим внешним текстовым данным с помощью внешних таблиц из базы данных и обновить существующие данные в базе данных с помощью операторов SQL, которые вам нравятся и используются, например,
INSERT
иMERGE
т. Д.В большинстве случаев использование утилит, предоставляемых Oracle, является лучшим способом выполнения ETL. И поскольку ваш вопрос звучит скорее как административный, я предлагаю вам взглянуть на мой предыдущий пост на DBA Stack Exchange «Обновление базы данных Oracle из CSV» .
ОБНОВЛЕНИЕ: Этот подход работает очень хорошо для чтения внешних данных в базе данных. Как правило, вы определяете внешний формат данных каждый раз, когда вам нужно обработать простой текстовый файл, который имеет новый формат. После создания внешней таблицы вы можете запросить ее, как настоящую таблицу базы данных. Всякий раз, когда есть новые данные для импорта, вы просто заменяете базовый файл (ы) на лету без необходимости воссоздания внешней таблицы. Поскольку внешняя таблица может запрашиваться как любая другая таблица базы данных, вы можете написать операторы SQL для заполнения других таблиц базы данных.
Затраты на использование внешних таблиц обычно ниже по сравнению с другими методами, которые вы бы внедрили вручную, потому что эта технология была разработана с учетом производительности с учетом архитектуры базы данных Oracle.
источник
Я думаю, что вы должны использовать SQL * Loader для загрузки файла CSV во временную таблицу, а затем использовать оператор MERGE для вставки данных в рабочую таблицу.
SQL * Loader даст вам больше гибкости, чем внешние таблицы, и если вы используете прямую загрузку, это действительно быстро. И MERGE сделает именно то, что вам нужно - вставьте новые записи и обновите существующие.
Несколько ссылок для начала:
http://docs.oracle.com/cd/B19306_01/server.102/b14215/ldr_concepts.htm
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016 .htm
источник
PreparedStatements сделает создание запросов на вставку или обновление очень быстрым. У вас должно быть три
PreparedStatements
: один для вставки, один для обновления и один для проверки, находится ли строка в таблице. Если вы можете сохранить идентификаторы между CSV-файлом и новой базой данных, то проверка наличия строки с использованием поля primaryID также должна быть очень быстрой.Использование пакетной вставки может повысить производительность. Когда вы просматриваете файл CSV, вы затем проверяете, существует ли уже строка, а затем либо обновляете, либо добавляете строку в команду пакетной вставки. Вы должны проверить этот вопрос SO для сравнения скорости этих двух подходов.
Если этот импорт базы данных необходимо выполнять регулярно, а производительность - это проблема с использованием метода, который я описал выше, тогда вы можете попробовать выполнить задачу с несколькими рабочими потоками. Используйте столько потоков, сколько их процессоров на компьютере, на котором выполняется этот код.
Каждый поток получает свое собственное соединение с БД, и когда ваш код перебирает файл, строки CSV могут передаваться различным потокам. Это намного сложнее, поэтому я сделал бы это только в том случае, если бы меня заставили требования к производительности.
источник