HyperSQL(HSQLDB):大量的插入性能

我有一个应用程序必须将大约1300万行大约10个平均长度的字符串插入到嵌入式HSQLDB中。 我一直在调整东西(批量大小,单线程/multithreading,缓存/非缓存表,MVCC事务,log_size / no日志,定期调用checkpoint ,……),它仍然需要7个小时的16核, 12 GB机器。

我之所以选择HSQLDB,是因为我认为如果我充分利用所有这些核心,我可能会获得可观的性能提升,但我真的开始怀疑我的决定。

有人能告诉我银弹吗?

使用CACHED表,磁盘IO占用大部分时间。 不需要多个线程,因为您要插入同一个表中。 显着提高性能的一件事是重用单个参数化的PreparedStatment,为每个行插入设置参数。

在您的计算机上,通过对内存映射IO使用大的NIO限制,可以显着提高IO。 例如SET FILES NIO SIZE 8192 。 大型号需要64位JVM才能生效。

http://hsqldb.org/doc/2.0/guide/management-chapt.html

要在批量插入期间减少IO,请使用SET FILES LOG FALSE并且在插入结束之前不要执行检查点。 详情如下:

http://hsqldb.org/doc/2.0/guide/deployment-chapt.html#dec_bulk_operations

更新:下面有1600万行的插入测试产生了1.9 GigaByte .data文件,并且在平均2核处理器和7200 RPM磁盘上只花了几分钟。 关键是大量的NIO分配。

 connection time -- 47 complete setup time -- 78 ms insert time for 16384000 rows -- 384610 ms -- 42598 tps shutdown time -- 38109 

检查您的应用程序正在做什么。 首先要看的是taskmanager(或OS特定的可比较)和visualvm中的资源利用率。

造成不良表现的好候选人:

  • 磁盘IO
  • 垃圾收集器

H2Database可以为您提供比HSQLDB稍好的性能(同时保持语法兼容性)。

在任何情况下,您可能希望尝试使用更高的延迟来同步到磁盘以减少随机访问磁盘I / O. (即SET WRITE_DELAY

希望您正在进行批量INSERT语句,而不是每行一次插入。 如果没有,请尽可能这样做。

根据您的应用程序要求,您可能最好使用键值存储而不是RDBMS。 (您是否经常需要插入1.3 * 10 ^ 7个条目?)

您的主要限制因素是对磁盘的随机访问操作。 我非常怀疑你所做的任何事情都会受到CPU限制。 (看看top ,然后将它与iotop进行比较!)

有这么多记录,也许您可​​以考虑切换到NoSQL DB。 当然,这取决于您需要存储的数据的性质/格式。