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。 当然,这取决于您需要存储的数据的性质/格式。