如何加快以下JDBC插入/导入过程?

时间:2018-08-11 11:21:01

标签: java mysql jdbc

所以基本上我有2个名为snomed_conceptdata的表,其中有(454772行)和
“ snomed_descriptiondata”(1383698行)。根据此代码,我目前正在尝试将记录插入到名为snomedinfo_data的表中,该表正在工作,但插入/导入过程正在缓慢进行。我怀疑这是因为嵌套的while循环的处理时间过长。

是否有另一种方法可以使导入/插入过程快速发生。

包Snomed.Snomed;

import java.sql.PreparedStatement;
import java.sql.ResultSet;

import catalog.Root;

public class Snomedinfo {
    public void snomedinfoinsert()
    {
    Root oRoot = null;
    ResultSet oRsSelect = null;
    PreparedStatement oPrStmt = null;
    PreparedStatement oPrStmt2 = null;
    PreparedStatement oPrStmtSelect = null;
    String strSql = null;
    String strSql2 = null;
    String snomedcode=null;
    ResultSet oRs = null;
    String refid = null;
    String id = null;
    String effectivetime = null;
    String active = null;
    String moduleid = null;
    String conceptid = null;
    String languagecode = null;
    String typeid = null;
    String term = null;
    String caseSignificanceid = null;
    try{
    oRoot = Root.createDbConnection(null);

    strSql = "SELECT  id FROM snomed_conceptdata WHERE active=1 ";
    oPrStmt2 = oRoot.con.prepareStatement(strSql);
    oRsSelect = oPrStmt2.executeQuery();
    while (oRsSelect.next()) {
        snomedcode = Root.TrimString(oRsSelect.getString("id"));

        strSql2 = "SELECT  * FROM snomed_descriptiondata WHERE conceptid =? AND active=1  ";
        oPrStmtSelect = oRoot.con.prepareStatement(strSql2);
        oPrStmtSelect.setString(1,snomedcode);
        oRs =oPrStmtSelect.executeQuery();
        while (oRs.next()) {
            refid = Root.TrimString(oRs.getString("refid")); 
            id = Root.TrimString(oRs.getString("id"));
            effectivetime = Root.TrimString(oRs.getString("effectivetime"));
            active = Root.TrimString(oRs.getString("active"));
            moduleid = Root.TrimString(oRs.getString("moduleid"));
            conceptid = Root.TrimString(oRs.getString("conceptid"));
            languagecode = Root.TrimString(oRs.getString("languagecode"));
            typeid = Root.TrimString(oRs.getString("typeid"));
            term = Root.TrimString(oRs.getString("term"));
            caseSignificanceid = Root.TrimString(oRs.getString("caseSignificanceid"));

            String sql = "INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid) VALUES( ?, ?, ?,?,?,?,?,?,?,?)";
            oPrStmt = oRoot.con.prepareStatement(sql);
            oPrStmt.setString(1, refid);
            oPrStmt.setString(2, id);
            oPrStmt.setString(3, effectivetime);
            oPrStmt.setString(4, active);
            oPrStmt.setString(5, moduleid);
            oPrStmt.setString(6, conceptid);
            oPrStmt.setString(7, languagecode);
            oPrStmt.setString(8, typeid );
            oPrStmt.setString(9, term);
            oPrStmt.setString(10, caseSignificanceid);
             oPrStmt.executeUpdate();

        }

    }
    System.out.println("done");
    }

    catch (Exception e) {
        e.printStackTrace();

    }

    finally {

        oRsSelect = Root.EcwCloseResultSet(oRsSelect);
        oRs = Root.EcwCloseResultSet(oRs);
        oPrStmt = Root.EcwClosePreparedStatement(oPrStmt);
        oPrStmt = Root.EcwClosePreparedStatement(oPrStmt2);
        oPrStmt = Root.EcwClosePreparedStatement(oPrStmtSelect);
        oRoot = Root.closeDbConnection(null, oRoot);
    }
}
    public static void main(String args[] ) throws Exception 
      { 


      Snomedinfo a = new Snomedinfo();
      a .snomedinfoinsert();

      }


}

2 个答案:

答案 0 :(得分:3)

您可以使用SQL Insert Into Select Query

INSERT INTO snomedinfo_data 
SELECT refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid FROM snomed_descriptiondata 
WHERE conceptid =? AND active=1  

它将合并您的第二和第三查询,因此您可以避免不必要的迭代。

答案 1 :(得分:1)

批注中提到了批处理插入(我们将在稍后介绍),这是您可以执行的其他一些优化。

目前,您正在一张一张地选择用于插入的数据,因此,如果您插入100,000行,那么还要从数据库中选择100,000行。相反,您可以执行一个SQL语句,对两个表进行联接:

...
    strSql2 = "SELECT d.* FROM snomed_conceptdata c, snomed_descriptiondata d WHERE c.active = 1 and conceptid = c.id AND d.active = 1";
    oPrStmtSelect = oRoot.con.prepareStatement(strSql2);
    oPrStmtSelext.setFetchSize(100);
    oRs = oPrStmtSelect.executeQuery();
    while (oRs.next()) {
...

删除第一个select语句和while循环,您应该已经大大提高了性能。

下一次性能提升可以来自只准备一次插入语句。所以放

        String sql = "INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid) VALUES(?,?,?,?,?,?,?,?,?,?)";
        oPrStmt = oRoot.con.prepareStatement(sql);
while循环之外的

。摆脱所有这些选择语句后,增加的幅度不应该那么大,但是仍然如此。

最后,除了调用oPrStmt.executeUpdate();之外,您还可以通过调用oPrStmt.addBatch()将执行添加到批处理中。这将收集内存中的语句,并通过调用oPrStmt.executeBatch()在一个事务中执行所有语句。如果将过多的语句添加到批处理中,您将以OutOfMemoryError结尾,因此您可以保留添加的语句的计数,并在达到阈值(例如)后执行批处理。 1000。