在过去的几天里,我一直在试验很长时间,将tar.gz(约1.45M个不同大小的不同文件)中的结构化(xml)数据转换为更友好的格式到数据库中。
我不确定我可能会透露哪些数据或用例,但我会尽力解释自己的努力。
我有一个表,其中包含以下列类型(MySQL; InnoDB):
int(11) PK NN UQ
varchar(150) NN
varchar(400) NN
text
text NN
varchar(45) NN UQ
varchar(80) NN
date NN
text
varchar(300)
varchar(300)
varchar(500)
varchar(260)
varchar(200)
varchar(45)
仅查看数据+解析就遍历整个tar大约需要90秒+/-:
try (TarArchiveInputStream tarArchiveInputStream =
new TarArchiveInputStream(
new BufferedInputStream(
new GzipCompressorInputStream(
new FileInputStream(tarLocation))))){
...
while ((entry = tarArchiveInputStream.getNextTarEntry()) != null && processedTarEntries < maxNumber) {
...PARSING + SOME STATISTICS....
}
}
我希望以下代码对我的迭代过程有足够的了解;如果不是,我将尝试提供更多(本示例中使用totalCount生成人工ID)。准备好的语句是“常规” INSERT INTO语句。
setPreparedStatementValues(preparedStatement, record, totalCount[0]++);
preparedStatement.addBatch();
counter[0]++;
if (counter[0] == BATCH_SIZE){
counter[0] = 0;
preparedStatement.executeBatch();
connection.commit();
watch.stop();
System.out.println("Elapsed time for batch " + (totalCount[0] / BATCH_SIZE) + ": " + watch.getTime());
watch.reset();
watch.start();
}
sout输出的相关部分如下(批量大小5k / 10k没什么大不同):
Elapsed time for batch 29: 3430
Elapsed time for batch 30: 3400
Elapsed time for batch 31: 3553
Elapsed time for batch 32: 3405
Elapsed time for batch 33: 3509
Elapsed time for batch 34: 3544
Elapsed time for batch 35: 6124
Elapsed time for batch 36: 5273
Elapsed time for batch 37: 9171
Elapsed time for batch 38: 8922
Elapsed time for batch 39: 24878
Elapsed time for batch 40: 68124
Elapsed time for batch 41: 70886
Elapsed time for batch 42: 78856
Elapsed time for batch 43: 80879
Elapsed time for batch 44: 85223
Elapsed time for batch 45: 92639
Elapsed time for batch 46: 80106
直到第40批之前的某个时间为止,时间似乎是线性的,此后爆炸。此输出来自最大300k条目的实验,但我尝试将其分成两个分别为150k条目的运行。输出与尝试一次完成全部300k十分相似。
如果能提出建议,我将不胜感激,或者建议如何加快速度!