我有一个应用程序必须将大约1300万行大约10个平均长度的字符串插入到嵌入式HSQLDB中。我一直在调整东西(批量大小,单线程/多线程,缓存/非缓存表,MVCC事务,log_size / no日志,常规调用checkpoint
,...),它仍然需要7个小时一台16核,12 GB的机器。
我之所以选择HSQLDB是因为我认为如果我充分利用所有这些核心,我可能会获得可观的性能提升,但我真的开始怀疑我的决定。
有谁能告诉我银弹?
答案 0 :(得分:5)
使用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
答案 1 :(得分:1)
检查您的应用程序正在执行的操作。首先要看的是taskmanager(或OS特定的可比较)和visualvm中的资源利用率。
造成不良表现的好候选人:
答案 2 :(得分:1)
H2Database可能会比HSQLDB提供更好的性能(同时保持语法兼容性)。
在任何情况下,您可能希望尝试使用更高的延迟来同步到磁盘以减少随机访问磁盘I / O. (即SET WRITE_DELAY <num>
)
希望您正在进行批量INSERT
语句,而不是每行一次插入。如果没有,请尽可能这样做。
根据您的应用程序要求,您可能最好使用键值存储而不是RDBMS。 (您是否经常需要插入1.3 * 10 ^ 7个条目?)
您的主要限制因素是对磁盘的随机访问操作。我非常怀疑你所做的任何事情都会受到CPU限制。 (看看top
,然后将其与iotop
进行比较!)
答案 3 :(得分:0)
有这么多记录,也许您可以考虑切换到NoSQL DB。当然,这取决于您需要存储的数据的性质/格式。