Как быстрее вставлять записи

Мне нужно прочитать записи из файла CSV и сохранить их в базе данных Mysql.

Я знаю о «LOAD DATA INFILE», но в моем случае мне нужно получить одну запись из файла, проверить, имеет ли она допустимый формат/длину и т. д., а затем сохранить ее в базе данных.

// list to store records from CSV file
ArrayList<String> list = new ArrayList<String>();

//Read one line at a time
while ((nextLine = reader.readNext()) != null) 
{
   for (String number : nextLine) 
   {
      if (number.length() > 12 && number.startsWith("88"))
      {        
         list.add(number);
      } else if (number.length() > 9 && number.startsWith("54")) 
      {
         list.add(number);
      }
      else if (number.length() > 8 && number.startsWith("99"))
      {
         list.add(number);
      }
      else
      {
        // ....
      }

      // method to insert data in database
      insertInToDatabase(list);                     
   }
}

и способ вставки записи в БД: взято отсюда

private void insertInToDatabase(ArrayList<String> list) 
{
   try
   {
      String query = "INSERT INTO mytable(numbers) VALUES(?)";

        prepStm = conn.prepareStatement(query);

        for (String test : list) 
        {
            prepStm.setString(1, test);

            prepStm.addBatch();// add to batch
            prepStm.clearParameters();
        }

        prepStm.executeBatch();
    }
}

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


person pro_newbie    schedule 25.02.2015    source источник
comment
Вы можете дать более подробную информацию? Сколько строк примерно занимает CSV? содержать? Вы проверяли, сколько времени заняло чтение файла/запись в БД?   -  person eiselems    schedule 25.02.2015
comment
прямо сейчас для тестирования файл CSV содержит 90 тысяч записей, и вставка всех записей заняла около 45 минут.   -  person pro_newbie    schedule 25.02.2015
comment
Я имею в виду, вы проверяли, сколько времени требуется для чтения и вставки? Вы можете просто вставить три System.out.println(System.currentTimeMillis()). Один перед началом чтения, один после завершения чтения и один после завершения вставки в БД. Таким образом, вы можете определить, действительно ли вставка в БД (или сам анализ) настолько медленная   -  person eiselems    schedule 25.02.2015


Ответы (4)


Ответ @Khanna111 хорош.

Я не знаю, поможет ли это, но попробуйте проверить тип движка таблицы. Однажды я столкнулся с проблемой, при которой записи вставляются очень медленно. Я изменил движок с InnoDB на MyISAM, и вставка стала очень быстрой.

person nice guy    schedule 26.02.2015

Вам нужно будет использовать: «rewriteBatchedStatement», так как это оптимизация MYSQL, которая пытается сократить количество обращений к серверу за счет объединения вставок или обновлений в как можно меньшем количестве пакетов.

См.: https://anonymousbi.wordpress.com/2014/02/11/increase-mysql-output-to-80k-rowssecond-in-pentaho-data-integration/

Кроме того, в этой статье есть другие оптимизации. Надеюсь, это ускорит пакетную обработку.

РЕДАКТИРОВАТЬ 1: На этом сайте также есть четкое объяснение этого параметра: см.: MySQL и JDBC с параметром rewriteBatchedStatements=true

person Khanna111    schedule 25.02.2015
comment
Пробовал добавлять rewriteBatchedStatements=true, очень быстро вставляется, все записи вставляются за секунды. Но у меня есть уникальный индекс в поле, так что это дает мне исключение. [bugs.mysql.com/bug.php?id=6822] . Как-нибудь об этом? - person pro_newbie; 25.02.2015
comment
Это будет другой вопрос, и люди смогут ответить на него, как только вы его зададите. Так работает сайт. Вы можете решить это и задать другой. - person Khanna111; 25.02.2015

я думаю, что лучший подход - обработать файл csv с определенными правилами, а затем создать из него еще один csv, и как только выходной csv будет подготовлен. загружать данные в файл.

это будет довольно быстро.

person anurag gupta    schedule 25.02.2015

Если вы хотите вставить через свое собственное приложение, создайте пакетный запрос, подобный этому, и выполните его на сервере MySQL.

String query = "INSERT INTO mytable(numbers) 
                VALUES (0),
                       (1),
                       (2),
                       (3)";
person Sujit Rai    schedule 25.02.2015