我有一个应用程序,它必须将大约1300万行大约10个平均长度的字符串插入到嵌入式HSQLDB中。我一直在调整(批处理大小、单线程/多线程、缓存/非缓存表、MVCC事务、log_ size /无日志、对checkpoint的常规调用等)而且在16核、12 GB的机器上仍然需要7个小时。
我选择了HSQLDB,因为我认为如果我能很好地利用所有这些核心,我可能会有很大的性能提升,但我开始认真地开始怀疑我的决定。
有人能给我看看银弹吗?
发布于 2012-04-24 16:12:09
对于缓存表,磁盘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核处理器和7200RPM磁盘上只需要几分钟。关键是大量的NIO分配。
connection time -- 47
complete setup time -- 78 ms
insert time for 16384000 rows -- 384610 ms -- 42598 tps
shutdown time -- 38109 发布于 2012-04-24 15:29:17
检查您的应用程序正在做什么。首先要查看taskmanager (或特定于操作系统的可比性)和visualvm中的资源利用率。
可能导致性能不佳的优秀候选者:
发布于 2012-04-24 15:39:13
H2Database可能会给你提供比HSQLDB稍好的性能(同时保持语法兼容性)。
在任何情况下,您都可能希望尝试使用较高的延迟来同步到磁盘,以减少随机访问磁盘I/O。SET WRITE_DELAY <num>)
希望您正在执行批量INSERT语句,而不是每行一次插入。如果不是,如果可能的话,就这么做。
根据您的应用程序需求,使用键值存储可能比使用RDBMS更好。(您是否需要定期插入1.3*10^7条目?)
您的主要限制因素是对磁盘的随机访问操作。我非常怀疑您正在做的任何事情都是受CPU限制的。(看一看top,然后将它与iotop进行比较!)
https://stackoverflow.com/questions/10293517
复制相似问题