所以基本上我有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();
}
}
答案 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。