Java 提高此场景性能的方法
我有一张包含大量数据的地图(大约300000条记录) 并按如下所示进行迭代Java 提高此场景性能的方法,java,performance,for-loop,map,Java,Performance,For Loop,Map,我有一张包含大量数据的地图(大约300000条记录) 并按如下所示进行迭代 for (Map.Entry<String, List<ClassOBj>> entry : testMap .entrySet()) { // send email with map keys as email'id // email content is populated from the list // Perform a sql upd
for (Map.Entry<String, List<ClassOBj>> entry : testMap
.entrySet()) {
// send email with map keys as email'id
// email content is populated from the list
// Perform a sql update to the column with the dyanamic value generated here with the email'id
}
for(Map.Entry:testMap
.entrySet()){
//将地图键作为电子邮件id发送电子邮件
//从列表中填充电子邮件内容
//使用此处生成的带有email'id的动态值对列执行sql更新
}
如上所述,我担心在for
循环中执行上述操作会导致性能问题
更新:
情况是这样的。我正在迭代一个包含大量数据的地图
迭代时,我得到用户ID,我必须计算用户ID。例如,考虑<代码> USERID +一些常量< /代码>,这应该在数据库表中更新。< /P> 也应该与我的地图中的列表值一起添加到电子邮件内容中
所以我认为批量更新是不可能的,我的理解正确吗我应该遵循这种方法吗?或者使用其他方法我的建议是您可以使用
存储过程
。或者可以使用批处理更新来代替此
更多信息。您应该使用jdbc批量更新功能 在映射上迭代时,将批处理添加到准备的语句中。添加(比如)2000条记录后,调用stmt.batchUpdate(),它将快速更新2000条不同的记录 您可以在此处看到一些示例:
第二件事——如果可以的话,在每次批处理更新之后进行事务提交。300k记录的事务可能对您的数据库配置影响很大。将此更新拆分为多个事务将具有更好的性能—但前提是您不能在所有记录上都有事务。而不是在每个循环中更新数据库。请在完成循环后尝试更新数据库 有不同的方法来优化大型数据库更新。 其中最好的一个就是
- 将修改后的值插入临时表
- 从临时表更新原始表
还可以使用基于线程的排队机制发送电子邮件我会这样做。为操作准备数据 我假设您正在更新一个类似user的表,它应该具有唯一的Id
Map<String, String> emailIds = new HashMap<String, String>();
Map<String, String> emails = new HashMap<String, String>();
for (Map.Entry<String, List<ClassOBj>> entry : testMap.entrySet()) {
-- DONOT DO THIS// send email with map keys as email'id
-- DONOT DO THIS// email content is populated from the list
-- DONOT DO THIS// Perform a sql update to the column with the dyanamic value generated here with the email'id
emails.put(emailId, content);
emailIds.put(id, emailId);
}
bulkEmailSend(emails);
bulkEmailUpdate(emailIds);
Map emailIds=newhashmap();
Map emails=newhashmap();
for(Map.Entry:testMap.entrySet()){
--请勿执行此操作//将地图键作为电子邮件id发送电子邮件
--请勿执行此操作//从列表中填充电子邮件内容
--不要这样做//使用此处生成的带有email'id的动态值对列执行sql更新
emails.put(emailId、内容);
emailId.put(id,emailId);
}
电子邮件发送(电子邮件);
批量电子邮件更新(EmailID);
bulkEmailSend
和bulkEmailUpdate
是进行适当调用时应该编写的方法
因此,使用批量电子邮件发送和批量电子邮件ID更新方法将值更新回数据库。我将尝试总结上面提到的所有优点 你的选择是
无法针对您的需求给出具体的答案,但我希望这对改进它有所帮助:)for循环需要时间,原因有两个。
1) 单个电子邮件通过减少传输连接来改善它
2) 个人承诺通过 所以理想的做法是处理这两个问题,我建议对1000个批次进行处理,然后处理数字 范例
int BATCH_SIZE = 1000
conn = DriverManager.getConnection("username","password");
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
int count = 0;
Map<String, String> emails_map = new HashMap(BATCH_SIZE)<String, String>;
for (Map.Entry<String, List<ClassOBj>> entry : testMap
.entrySet()) {
String email = get_useremail();
String const_val = do_magic(); // this is how you are computing some constant
String body = construct_body();
count++;
String SQL = "YOUR UPDATE STATEMENT";
stmt.executeUpdate(SQL);
emails_map.put(email, body); // can create
if (count % BATCH_SIZE == 0) {
//commits all transcations
conn.commit();
//bulk send emails sending
//http://stackoverflow.com/questions/13287515/how-to-send-bulk-mails-using-javax-mail-api-efficiently-can-we-use-reuse-auth
bulk_emails_send(emails_map)
}
}
public void bulk_emails_send(Map<String, String> emails_map) {
// Get the default Session object through your setting
Session session = Session.getDefaultInstance(properties);
Transport t = session.getTransport();
t.connect();
try {
for (String email_id in emails_map) {
Message m = new MimeMessage(session);
//add to, from , subject, body
m.saveChanges();
t.sendMessage(m, m.getAllRecipients());
}
} finally {
t.close();
}
}
int批大小=1000
conn=DriverManager.getConnection(“用户名”、“密码”);
连接设置自动提交(错误);
语句stmt=conn.createStatement(
ResultSet.TYPE\u SCROLL\u不敏感,
结果集CONCUR_可更新);
整数计数=0;
Map email\u Map=新HashMap(批大小);
对于(Map.Entry:testMap
.entrySet()){
字符串email=get_useremail();
String const_val=do_magic();//这就是计算常数的方法
字符串体=构造体();
计数++;
String SQL=“您的更新语句”;
stmt.executeUpdate(SQL);
emails_map.put(email,body);//可以创建
如果(计数%BATCH_SIZE==0){
//提交所有转换
conn.commit();
//批量发送电子邮件发送
//http://stackoverflow.com/questions/13287515/how-to-send-bulk-mails-using-javax-mail-api-efficiently-can-we-use-reuse-auth
批量发送电子邮件(电子邮件地图)
}
}
公共无效批量电子邮件发送(映射电子邮件映射){
//通过设置获取默认会话对象
Session Session=Session.getDefaultInstance(属性);
Transport t=session.getTransport();
t、 connect();
试一试{
对于(ema中的字符串电子邮件\u id)