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

Java 如何加快以下JDBC插入/导入过程?,java,mysql,jdbc,Java,Mysql,Jdbc,因此,基本上我有两个名为snomed_conceptdata的表,其中包含(454772行)和 “snomed_descriptiondata”(1383698行)。根据此代码,我当前正试图将记录插入名为snomedinfo_data的表中,该表正在工作,但插入/导入过程正在缓慢进行。我怀疑这是因为嵌套的while循环在处理过程中花费的时间太长 是否有其他方法来执行此操作,以便可以快速执行导入/插入过程 包Snomed.Snomed import java.sql.PreparedStateme

因此,基本上我有两个名为
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();

      }


}

注释中提到了批插入(我们将在一分钟内讨论),下面是您可以执行的一些其他优化

目前,您正在逐个选择用于插入的数据,因此,如果您插入100000行,那么您也将从数据库中选择100000行。相反,您可以执行一条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
-循环,您应该已经有了显著的性能提升

性能的下一个提高可能来自只准备一次insert语句。所以说

        String sql = "INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid) VALUES(?,?,?,?,?,?,?,?,?,?)";
        oPrStmt = oRoot.con.prepareStatement(sql);
while
循环之外。增加的幅度不应该像去掉所有这些select语句时那样剧烈,但仍然如此


最后,不要调用
oPrStmt.executeUpdate()
您可以通过调用
oPrStmt.addBatch()
将执行添加到批处理中。这将收集内存中的语句,并通过调用
oPrStmt.executeBatch()
在一个事务中执行所有语句。如果向批处理中添加了太多语句,则会出现
OutOfMemoryError
,因此您可能会对添加的语句进行计数,并在达到阈值(例如1000)后执行批处理。

注释中提到了批处理插入(我们将在一分钟后讨论),下面是一些您可以执行的其他优化

目前,您正在逐个选择用于插入的数据,因此,如果您插入100000行,那么您也将从数据库中选择100000行。相反,您可以执行一条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
-循环,您应该已经有了显著的性能提升

性能的下一个提高可能来自只准备一次insert语句。所以说

        String sql = "INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid) VALUES(?,?,?,?,?,?,?,?,?,?)";
        oPrStmt = oRoot.con.prepareStatement(sql);
while
循环之外。增加的幅度不应该像去掉所有这些select语句时那样剧烈,但仍然如此

最后,不要调用
oPrStmt.executeUpdate()
您可以通过调用
oPrStmt.addBatch()
将执行添加到批处理中。这将收集内存中的语句,并通过调用
oPrStmt.executeBatch()
在一个事务中执行所有语句。如果向批处理中添加了太多语句,则会出现
OutOfMemoryError
,因此您可能会对添加的语句计数,并在达到阈值(例如1000)后执行批处理。

您可以使用

它将合并您的第二个和第三个查询,这样您就可以避免不必要的迭代

您可以使用



它将合并您的第二个和第三个查询,这样您就可以避免不必要的迭代

通常,它是这样工作的,只需一个查询调用:
insert into t(col1,col2)从其他表中选择colX,colY
Try batch updates。如果在一个事务中执行多个更新,速度会快得多。如何避免使用那些嵌套的while循环??有没有更好的选择??你必须使用Java吗?这是必须的吗?使用MySQL转储和加载可以很快做到这一点:是的,我必须在java jdbc中做到这一点。一般来说,它通过一个查询调用就可以这样工作:
insert-into t(col1,col2)选择colX,colY from other_table
Try batch updates。如果在一个事务中执行多个更新,速度会快得多。如何避免使用那些嵌套的while循环??有没有更好的选择??你必须使用Java吗?这是必须的吗?使用MySQL转储和加载可以很快做到这一点:是的,我必须只在java jdbc中这样做。对MySQL进行批插入非常重要。是否有必要在“snomed_descriptiondata”的“conceptid”列中添加索引table@JohnSmith独立于这些建议:是的,否则,如果您从表中选择数据,您将进行完整的表扫描。那么仅添加索引就足够了???@JohnSmith足够做什么?避免上述改变?否。如果逐行保留选择,则数据库中仍可能有数十万条SQL语句,而不是一条。对MySQL的批插入也很重要。是否有必要向“snomed_descriptiondata”的“conceptid”列添加索引table@JohnSmith独立于这些建议:是的,否则,如果您从表中选择数据,您将进行完整的表扫描。那么仅添加索引就足够了???@JohnSmith足够做什么?避免上述改变?不可以。如果逐行保留选择,则数据库中仍可能有数十万条SQL语句,而不是一条。