【发布时间】:2015-05-19 03:41:14
【问题描述】:
我有一个 CSV,它有 3400 万行长。是的,不开玩笑。
这是由parser tracer 生成的 CSV 文件,然后将其导入corresponding debugging program。
问题出在后者。
现在我一一导入所有行:
private void insertNodes(final DSLContext jooq)
throws IOException
{
try (
final Stream<String> lines = Files.lines(nodesPath, UTF8);
) {
lines.map(csvToNode)
.peek(ignored -> status.incrementProcessedNodes())
.forEach(r -> jooq.insertInto(NODES).set(r).execute());
}
}
csvToNode 只是一个映射器,它将String(CSV 的一行)转换为NodesRecord 以供插入。
现在,一行:
.peek(ignored -> status.incrementProcessedNodes())
嗯...方法名称几乎说明了一切;它增加了status 中的一个计数器,它反映了到目前为止处理的行数。
发生的情况是每秒都会查询此status 对象以获取有关加载过程状态的信息(我们在这里谈论的是 3400 万行;加载它们大约需要 15 分钟)。
但现在 jooq 有了这个(取自他们的文档),可以直接从 CSV 加载:
create.loadInto(AUTHOR)
.loadCSV(inputstream)
.fields(ID, AUTHOR_ID, TITLE)
.execute();
(虽然我个人从不使用 .loadCSV() 重载,因为它没有考虑 CSV 编码)。
当然,JooQ 会设法将其转化为合适的构造,以便为这个或那个数据库引擎最大化吞吐量。
然而,问题是我丢失了从当前代码中获得的“按秒”信息......如果我用select count(*) from the_victim_table 替换查询,那就有点不合时宜了,更不用说这可能是需要很长时间。
那么,我如何获得“两全其美”?也就是说,有没有办法使用“优化的 CSV 加载”和查询,足够快,并且在任何时候,到目前为止已经插入了多少行?
(注意:如果有关系,我目前使用 H2;还计划推出 PostgreSQL 版本)
【问题讨论】:
标签: java sql batch-processing h2 jooq