我想通过JDBC将200000行插入到表中,connection.My表有三列:DISTRICT1(Id、Name、country).I使用多线程执行插入操作,它在不到1 minutes.Then中插入数据--我再次尝试对DISTRICT2(Id、Name、country)表执行类似的操作,在这种情况下,需要很长时间的foreign-key-relationship (超过2小时)来插入行(就像对单线程一样),与两个表之间唯一的区别是DISTRICT2表有一个字段Id,该字段通过链接到其他表,而DISTRICT1表没有这种关系。还有一个区别是mysql引擎,DISTRICT1有ENGINE=MyISAM,而为DISTRICT2提供ENGINE=INNODB,当我使用语句 .Does代替语句.Does时,它也给了java.lang.OutOfMemoryError一些与连接池有关的信息
请告诉,当表有某种关系时,为什么要花很长时间?我使用了相同的程序代码来插入两个表。
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 1; i <200001; i=i+10000) {
Runnable worker = new MyRunnable4District(i);
executor.execute(worker);
}
executor.shutdown();
}类MyRunnable4District如下所示
public class MyRunnable4District implements Runnable {
public int size;
public MyRunnable4District(int n) {
this.size = n;
}
public void run() {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/project",
"root", "root");
String[] countries = { "ARGENTINA", "US", "UK", "INDIA", "UKRAINE",
"CHINA" };
for (int id = size; id < size + 10001; id++) {
int districtId = id;
String districtName ="columbia"+id;
String districtCountry = countries[id % 6];
String query="INSERT INTO district "+"VALUES ("+districtId+",'"+districtName+"','"+districtCountry+"')";
//PreparedStatement stmnt =con.prepareStatement(query);
Statement stmnt =con.createStatement();
stmnt.executeUpdate(query);
}
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
try {
con.close();
System.out.println("thread number with size "+size+" completed");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}发布于 2011-01-14 18:22:11
你没有清理你的资源。在你使用完之后,你应该对你的陈述进行关。
但是,使用PreparedStatement并使用不同的参数重用它将是一个更好的主意。
另外,您可能需要考虑使用负载数据信息。
发布于 2011-01-22 20:36:49
您应该尝试多值插入。例如:
INSERT INTO district VALUES (id1,name1,country1),(id2,name2,country2),(id3,name3,country3);这可以提供显著的性能提升,特别是在连接到远程服务器时需要这样做的时候。除了减少网络往返(甚至本地机器上的进程外调用)之外,服务器还必须处理更少的查询。另外,如果为InnoDB启用了自动提交,那么现在每个批处理将有一个事务,而不是每个语句一个。
如果您将rewriteBatchedStatements选项设置为true,Connector/ JDBC驱动程序将为您执行此操作。我认为这个特性是在3.1.x驱动程序发行版中为像您这样的简单插入添加的。在以后的版本中,rewriteBatchedStatements得到了增强,以支持更复杂的语句。在此页上搜索rewriteBatchedStatements。
或者可以重写代码来手动构造多值insert语句。需要注意的一件事是最大的数据包大小。您需要确保insert语句保持在该值以下。因此,要么在导入数据时使封包变得非常大,要么在批处理接近max_allowed_packet时将其分解。
https://stackoverflow.com/questions/4694474
复制相似问题