对于大结果集,如何使H2返回结果更快?

时间:2014-11-15 11:35:43

标签: hibernate query-optimization h2

在批处理应用程序中,我使用临时基于文件的H2数据库来存储3M行。数据库大小为9GB。

在批处理结束时,我将数据库的内容导出到换行符分隔的JSON文件。这基本上是一个大的Hibernate JOIN查询,然后在结果集上迭代以在结果文件中写入。生成的文件大小约为5GB。

执行JOIN查询以获取ScrollableResults个对象大约需要6分钟。我可以对此进行优化,但对我来说还是可以的。

我的问题是,从ScrollableResults复制到报告文件的下一个操作非常慢。完成需要30分钟。快速检查VisualVM的CPU采样器,可以看出大部分时间花费在org.h2.store.WriterThread.run()org.h2.store.fs.FileDisk.read()上。

enter image description here

由此我明白,花费大部分时间的是将结果写入结果缓冲区h2保留在硬盘上并从中读取。由于结果集非常大,我无法将其存储在内存中。我的其他选择是什么让这个操作运行得更快?

注意:为了确保磁盘性能(它是Google Compute Engine上的SSD磁盘)不对此负责,我使用cp命令将9GB db备份到另一个文件,并且花了5分钟。

1 个答案:

答案 0 :(得分:0)

对结果的一些解释:WriterThread的CPU时间为0,因为它在大多数时间都在等待(休眠)。 FileDisk.read可以从数据库文件中读取,也可以从大型结果集读取(在H2中,大多数情况下将大型结果集写入磁盘)。所以现在还不是很清楚问题是否真的是创建了一个临时结果集。

要分析性能瓶颈,我要做的是分析最常见的堆栈跟踪。这将显示它缓慢的位置和原因。现在,你所看到的只是它很慢,但不是为什么(其他方法称之为)。

如果问题确实是临时结果集存储到磁盘,那么我所知道的唯一解决方案(截至目前)是避免使用大型结果集。