提高此方案性能的方法

我有一张填充了大量数据的地图(大约300,000条记录)

并按如下方式迭代,

for (Map.Entry<String, List> 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循环中执行的上述操作会导致性能问题。

更新:

情景是。 我正在迭代一个包含大量数据的地图,

迭代它我得到用户ID,我必须计算用户ID。例如,考虑userid+some constants ,这应该在数据库表中更新。

并且还应该与我的地图中的列表值一起添加到电子邮件内容中

所以我认为批量更新是不可能的,我的理解是正确的吗?

我应该遵循这种方法吗? 或者选择任何其他想法

由于两个原因,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 emails_map = new HashMap(BATCH_SIZE); for (Map.Entry> 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 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(); } } 

而不是在每个循环中更新数据库。尝试在完成循环后更新数据库。

有不同的方法来优化大型数据库更新。 最好的一个是

  • 将修改后的值插入临时表中
  • 从临时表更新原始表

还使用基于线程的排队机制来发送您的电子邮件

您应该使用jdbc批量更新function。

在迭代地图时,您可以将批处理添加到预准备语句中。 添加(比方说)2000条记录后,可以调用stmt.batchUpdate(),它将以快速方式更新2000条不同的记录。

您可以在此处看到一些示例:

http://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/

第二件事 – 如果可以的话,在每个batchUpdate之后进行事务提交。 对于数据库配置,300k记录的事务可能很多。 将此更新拆分为多个事务将具有更好的性能 – 但前提是您不能在所有记录上进行事务处理。

我的建议是你可以使用Stored procedure 。 或者使用可以使用批量更新而不是这个。

有关sql批量更新的更多信息。

我会做这样的事情。 准备操作数据。

我想你正在更新一个像用户这样应具有唯一ID的表。

 Map emailIds = new HashMap(); Map emails = new HashMap(); for (Map.Entry> 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); 

bulkEmailSendbulkEmailUpdate是应该编写以进行适当调用的方法。

因此,使用批量电子邮件发送和批量emailId更新方法将值更新回数据库。

我将尝试总结上面提到的所有优点。

你的选择是,

  1. 尽可能使用multithreading,但请注意multithreading需要额外的内存(堆转储和应用程序将关闭)。
  2. 另一个不错的选择是使用批量更新,但批量更新再次带来了数据库端锁定时间更长的成本。 所以明智地使用它,因为线程将等待一个线程完成更新,因为更新将采取独占锁定,即不可能共享。

  3. 尝试与异步作业(特别是邮件)一起进行线程尝试使用不同的服务器/进程进行邮件处理并异步向邮件服务器发送邮件请求,这非常快,因为您的邮件生成任务由其他进程处理(在实际邮件交换中)可以接受一些延迟,因此允许您的慢速邮件服务器,但应用程序服务器不允许。)

  4. 如果可能的话,在DB服务器上的存储过程中移动完整的Db更新逻辑,这将节省大量时间(经验法则:总是让A处理A设计/优化的任务,即DB设计用于比pgming语言更快的DB操作。 )

无法根据您的需要给出答案,但我希望这对改进它有帮助:)