hsqldb Cached Table转变
之前,使用HSQLDB的时候没有考虑客户端内存的大小,建立的表都是MemoryTable。这样,将表加载到客户端的时候,就会出现关于内存大小不够用的问题。昨天,打32个项目的PCB基线的时候,就出现了内存溢出的事情。
虽然,可以通过设置JVM的大小改变JVM所能占有的内存大小。btw:这里需要设置服务器端和客户端。
set JAVA_OPTS=-server -Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m在客户端,直接设置JAVA控制台的JRE内存大小设置就可以了。能解决一定问题,但是不能解决所有的问题。
今天仔细查看了HSQLDB的说明文档,原来MemoryTable表在数据库初始化的时候会被完全读写到内存当中,假设我的数据库有60M的话,这60M的内存将一下就读入到内存中去,当然就会占用大量的内存资源。等数据库关闭的时候,内存中的数据就会写到.Script文件当中去。当然还不包括对数据库进行的操作所耗费的资源等等,这么一下来,客户端耗费的资源就相当大了。
一个比较好的方法是将这种MemoryTable转变为CachedTable。这样的话
“CACHED表是在使用CREATECACHEDTABLE命令的时候生成的。它只有索引或部分数据是驻留在内存中的,所以可以允许生成容量为几百兆的表空间。CACHED表的另外一个优点,即使它存储了大量的数据,数据库引擎只需花费很短的时间就可以启动。它的不足是在速度上有所降低。如果你的数据集相对小的时候,尽量不要使用CACHED表。在小容量和大容量表共存的实际应用中,最好对哪些小容量的表使用默认的MEMORY表。”--摘自HSQLDB用户指南
"Ifonlymemorytables(CREATETABLEorCREATEMEMORYTABLE)areusedthenthedatabaseislimitedbythememory.Aminimumofabout100bytesplustheactualdatasizearerequiredforeachrow.IfyouuseCREATECACHEDTABLE,thenthesizeofthetableisnotlimitedbythememorybeyondacertainminimumsize.Thedataandindexesofcachedtablesaresavedtodisk.Withtexttables,indexesarememoryresidentbutthedataiscachedtodisk."--摘自HSQLDBFAQ
也就是说,如果我把其中比较大的MemoryTable转换为CachedTable的话,占用的内存资源会相对较少,但是速度是会降低。测试了一下,导出单个项目的数据到HSQLDB数据库中,如果使用Memory的话,需要32s,但是,使用CachedTable的话,需要45s,数据文件有6M。
由于产品马上就要发布了,这个时候修改可能不是很恰当。先评估一下可能的影响吧。
- 需要备份的数据。以前就单单备份了一个.script文件,现在需要将这些文件都要备份起来。〔修改备份文件的逻辑,改为备份文件夹,压缩为zip文件〕
- 数据传输到客户端,需要将备份的压缩文件夹,先解压缩。
- 不能根据Scipt文件来创建内存数据库。如果加入了CachedTable的话,scipt文件中的信息不全,不能通过这种方式去Rebuild内存数据库。现有内存数据库使用方式需要改变为文件数据库的使用方式。
- SHUTDOWNCOMPACT替换原来的SHUTDOWN命令。这样会使得生成的数据库文件大小稍微小一点。
这种统计的需求放到客户端去进行,真是难为客户端了,希望客户端的内存大点:)
真想把统计业务和系统常规业务分开,单独的统计系统来处理这些统计需求,就不会对常规业务系统造成影响了。不知道各位在处理统计需求的时候怎么处理?