java - 使用 JDBC:将数据从 tar.gz 传输到 MySQL db 在大约 200k 个条目后变得缓慢
问题描述
在过去的几天里,我一直在尝试将结构化 (xml) 数据从 tar.gz(约 1.45 万个相当小的不同文件)转换为更友好的格式到数据库中。
我不确定我可能会披露哪些数据或用例,但我会尽力解释我的努力。
我有一个包含以下列类型(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-output 的相关部分如下(批量大小 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 非常相似。
如果我错了,或者建议如何加快速度,我将非常感谢您提出我可能做错的建议!
解决方案
推荐阅读
- javascript - 我对从 webapi 到 angularjs 和 html 的 get 方法有疑问
- mysql - 查询:等于值不等于
- javascript - 如何在three.js中移动其位置时保持相机旋转指向原点?
- python - 复制文件夹和子文件夹,但仅使用 python 复制子文件夹中的第一个文件
- git - Git 尝试提交到 github 时抛出错误
- r - 基于数据框和向量之间的部分匹配过滤行
- python - 如何在另一列中保留最常出现的重复值
- angular - 我安装“@angular/cdk”并在导入 DragDropModule 时出错,我做错了什么?
- formula - 如何建立一个公式来隔离 Netsuite 中应收账款账龄的贷记金额?
- keytool - 警告:使用 -cacerts 选项访问 cacerts 密钥库