我是java的新手,还是多线程的新手。 面试官一次又一次地问我一个问题。 “给出一个csv文件-如果您要求读取java中的一个文件,该文件包含数百万条记录,然后在较短的时间内将这些记录插入数据库中。” 采访者还问我-如何利用“多线程,批处理和弹簧”之类的概念来解决上述问题?
我在Inernet上遵循了以下代码,但这看起来不太好,除了'PreparedStatement'之外,您还有其他选择吗? 甚至我在下面的代码中也看不到使用multithreadig。
public class Utility {
public static String getName(String fileURL)
throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
String fileName = "";
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String disposition = httpConn.getHeaderField("Content-Disposition");
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
}
return fileName;
}
}
答案 0 :(得分:0)
不是一个真正的答案,但是给您一些提示:
请注意,对于sql服务器,它可以接收的最大包大小有一个可配置的限制
询问csv文件的属性是什么
是否可以假设每个条目代表唯一的东西,而不是代表同一数据库条目的多行
检查该表的主键是什么
如果给出唯一性,则可以并行进行导入(分割文件)。 关闭主键可能是必须的,因此数据库不会锁定插入命令。
如果未提供唯一性,则可能需要预处理文件以使条目唯一。
考虑批次大小: 好吧,我不是数据库专家,但我学到的知识都不大也不小。
不确定spring
指的是什么:
春天的框架,也许吗?
答案 1 :(得分:0)
SQL插入将锁定该表,使其无法进行进一步的操作,直到发出提交为止。因此,所有插入将按顺序是FIFO。还记得ACID属性吗?从学校?再次阅读。
插入不能使用多个线程来完成,没有用。因为,这些线程将继续等待获得对表的锁定,并且最终消耗的时间比在“ for循环”中花费的时间更多。
批量插入是Java中提供的一项功能,可以一次插入多个条目,但是从数据库方面来看,它是一次提交的n次插入。提供它以简化编程。
现在,解决方案。
要将数百万条记录插入数据库表中,可以通过执行以下操作来实现。 创建许多临时表。创建一打线程。将您的数百万条记录分割成十几个线程,这些线程将数据插入各自的表中。 最后,将这几十个表的所有数据合并到最终表中。 您将比单循环插入快12倍。 此方法的性能也取决于您的计算机配置。您需要足够的核心和足够的内存来执行此操作。
为了获得更好的性能,所有这几十个表都不应具有索引,这会稍微提高插入性能。
如果您有一台好的服务器,请使用100个线程和100个表。您将比单循环快100倍。
如果您在任何银行或零售公司的Live DB上执行此类操作,则将在EOD前被解雇。此类高性能操作必须预先计划,并且必须传达给数据库管理员,并且只有在收到批准电子邮件后才能进行。