2015-11-12 5 views
0

Я хочу вставить 700 миллионов строк в таблицу, которая определяется следующим образом.Улучшить скорость вставки в mysql

CREATE TABLE KeywordIndex (id INT PRIMARY KEY AUTO_INCREMENT, 
keyValue VARCHAR(45) NOT NULL, postings LONGTEXT NOT NULL); 

Чтобы вставить данные в таблицу я сначала проверить, если KeyValue существует ли обновить значение проводки путем конкатенации новое значение старого значения. В противном случае вставьте данные в новую строку таблицы. Кроме того, если размер сообщений больше, чем его определение, я рассматриваю новую строку для написания расширений сообщений keyValue. В моей реализации вставка 70 294 записей заняла 12 часов !!!!

(я не эксперт базы данных, поэтому код, который я написал может быть основано на неправильном фундаменте. Пожалуйста, помогите мне понять мои ошибки :))

Я прочитал this page, но я не мог найти решение для моей проблемы.

Я добавляю код, который я написал для этого процесса.

public void writeTermIndex(
      HashMap<String, ArrayList<TermPosting>> finalInvertedLists) { 

     try { 


      for (String key : finalInvertedLists.keySet()) { 

        int exist=ExistTerm("KeywordIndex",key); 
        ArrayList<TermPosting> currentTermPostings=finalInvertedLists.get(key); 
         if (exist>0) 
         { 
          String postings=null; 
          String query = "select postings from KeywordIndex where keyValue=?"; 

          PreparedStatement preparedStmt = conn.prepareStatement(query); 

          preparedStmt.setString (1, key);  
          ResultSet rs=preparedStmt.executeQuery(); 
          if(rs.next()) 
           postings=rs.getString("postings"); 

          postings=postings+convertTermPostingsToString(currentTermPostings); 

          if(getByteSize(postings)>65530) 
           insertUpdatePostingList("KeywordIndex",key,postings); 
          else{ 

           updatePosting("KeywordIndex",key,postings); 
           rs.close(); 
           preparedStmt.close(); 
          } 

         } 

         else 
         { 
          String postings=convertTermPostingsToString(currentTermPostings); 
          if(getByteSize(postings)>65530) 
          insertPostingList("KeywordIndex",key,postings); 

          else 
           insetToHashmap("KeywordIndex",key,postings); 
         } 

       } 

     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
} 
+0

Точно, как этот код не работает? –

+4

Рассмотрим [объемная загрузка] (https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html), затем вызовите процедуру для объединения записей между таблицами, затем отпустите загруженный навалом стол. Индивидуальные вызовы из вашего приложения в базу данных будут медленными ... Накладные расходы для пакета, накладные расходы для подключения к базе данных и вызова. IMO лучше загружать массовую загрузку и позволяет базе данных «MERGE» устанавливать в процедуру устранение трафика и накладных расходов. Процедура состоит всего из двух утверждений, вставляющих все несуществующие записи, обновление существующих записей. намного быстрее все в db – xQbert

+0

@MarcB это работает, но ** медленно **. – Suri

ответ

0

Вы должны думать об использовании executeBatch() для вставки (я не говорю о той части нагрузки вашего запроса). В зависимости от используемой базы данных, представления могут многое изменить (см тест в конце этого page) (я когда-то тестировал с Oracle Database)

Что-то вроде:

PreparedStatement statement = null; 
try { 
    statement = getConnection().prepareStatement(insertQuerry); 

    for (/*...*/) { 
     statement.clearParameters(); 
     statement.setString(1, "Hi");     
     statement.addBatch(); 
    } 

    statement.executeBatch(); 
} catch (SQLException se) { 
    //Handle exception 
} finally { 
    //Close everything 
} 
+0

Не могли бы вы объяснить больше, что вы сказали в разделе вставки, я использую executeBatch, но я вставляю после некоторой проверки, что это keyValue существует или нет? Не могли бы вы объяснить более подробно – Suri

Смежные вопросы