2016-09-24 25 views
0

ここに私の 'venprices'テーブルの構造があります。バルク挿入操作が遅すぎる

+-------+-------------+------+-----+---------+-------+ 
| Field | Type  | Null | Key | Default | Extra | 
+-------+-------------+------+-----+---------+-------+ 
| conid | int(10)  | NO | PRI | NULL |  | 
| rate | double  | YES |  | NULL |  | 
| venid | varchar(50) | NO | PRI |   |  | 
+-------+-------------+------+-----+---------+-------+ 

JAVAコード:

new Thread(){ 
      public void run(){ 
       XSSFWorkbook myWorkBook; 
       XSSFSheet mySheet = null; 
       Iterator<Row> rowIterator = null; 
       String venid = null, errorlog = null; 
       int code; 
       double rate; 
       int rows, maxcount; 
       PreparedStatement ps = null; 
       Connection con; 
       ProgressMonitor pm; 
       try { 
        myWorkBook = new XSSFWorkbook(new FileInputStream(new File(jTextField1.getText()))); 
        mySheet = myWorkBook.getSheetAt(0); 
        rowIterator = mySheet.iterator(); 
        rowIterator.next(); 
        venid = jComboBox1.getItemAt(jComboBox1.getSelectedIndex()); 
        con = Mycon.getConnection(); 
        ps = con.prepareStatement("DELETE FROM venprices WHERE venid = ?"); 
        ps.setString(1, venid); 
        ps.executeUpdate(); 
        ps.clearBatch();  
        ps = con.prepareStatement("insert into venprices values (?,?,?)"); 
       } catch(Exception ioe) { 
        JOptionPane.showMessageDialog(null, ioe.getMessage()); 
       } 
        rows = 1;maxcount = mySheet.getLastRowNum(); 
        // Traversing over each row of XLSX file 
        while (rowIterator.hasNext()) 
        { 
         try{ 
          Row row = rowIterator.next(); 
          Iterator<Cell> cellIterator = row.cellIterator(); 
          Cell cell = cellIterator.next(); 
          code = (int) cell.getNumericCellValue(); 
          cell = cellIterator.next(); 
          rate = cell.getNumericCellValue(); 
          ps.setInt(1,code); 
          ps.setDouble(2,rate); 
          ps.setString(3, venid); 
          ps.addBatch(); 
          rows++; 
         }catch(Exception e){errorlog = errorlog + "\n" +rows+ e.getMessage();} 
        } 
        try{ 
         System.gc(); 
         ps.executeBatch(); 
        }catch(Exception e){e.printStackTrace();} 
        if(errorlog == null) 
         JOptionPane.showMessageDialog(null, "Import Successful. " + rows + " Records Imported."); 
        else 
         JOptionPane.showMessageDialog(null, "Error Log :\n"+errorlog); 
      } 
     }.start(); 

ユーザーがExcelファイルでシングルショットで周りに50,000レコードを挿入することが期待されます。しかし、クエリには約6〜7分かかります。 誰でも挿入操作時間を短縮するのに手伝ってもらえますか、挿入クエリのいくつかの調整を教えてください。 ありがとうございました!

編集1:要求どおり 、ここで私は、Javaの文法を知っているが、あなたのコードの先頭にMySQLのSTART TRANSACTIONBEGIN)を追加しないshow create table venprices

mysql> show create table venprices; 
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table  | Create Table                                                       | 
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| venprices | CREATE TABLE `venprices` (
    `conid` int(10) NOT NULL, 
    `rate` double DEFAULT NULL, 
    `venid` varchar(50) NOT NULL DEFAULT '', 
    PRIMARY KEY (`conid`,`venid`), 
    KEY `vepr` (`conid`,`rate`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
+1

'describe'は' show create table venprices'と同じくらい良いものではありません – Drew

+0

申し訳ありません。 –

+0

'show create table venprices'と入力してEnterキーを押し、結果を得て、一番上に[編集] – Drew

答えて

1

の結果です。最後にCOMMITを追加します。

なぜですか?

6〜7分で50Kの行を挿入すると、各行を独自のトランザクション(aaa autocommit=ON)に挿入するとよく似ています。これは、ディスク上のすべてのトランザクション処理のために遅いです。

50Kトランザクションを1トランザクションにすると、I/Oが大幅に少なくなり、より高速に実行されます。

2番目... 50Kの1行INSERTsを50 1000行INSERTsに変更すると、さらに10倍のスピードアップが得られます。これは、クライアントとサーバーの間の往復時間の大半、および解析時間のほとんどを避けるためです。 (Javaは、このようなを容易にするための特別なクラスを持っている場合は、再度、私は知りませんが、それは可能性があります。)

これら2つの変更がは、おそらくドリューのLOAD_DATA INFILEアプローチで競争力になります。

関連する問題