为什么在嵌入式HSQLDB上运行更新查询会占用大量内存?

时间:2018-06-05 08:50:21

标签: hsqldb

我使用的是HSQLDB 2.4.1(嵌入了缓存表)。我有一个大型数据库(行数约为2100万。数据库大小 5GB ) 我试图运行以下查询:

UPDATE TABLE_NAME SET COLUMN1=0

我尝试更改并使用这些属性,但最终这个更新语句消耗了大量内存,就好像它将整个数据库复制到内存中一样。

    properties.setProperty("hsqldb.large_data" , "true");
    properties.setProperty("hsqldb.log_data" , "false");
    properties.setProperty("hsqldb.default_table_type" , "cached");
    properties.setProperty("hsqldb.result_max_memory_rows" , "50000");
    properties.setProperty("hsqldb.tx" , "mvcc");
    properties.setProperty("sql.enforce_tdc_update" , "false");
    properties.setProperty("shutdown" , "true");
    properties.setProperty("runtime.gc_interval" , "100000");

当我在DBeaver中执行此查询时,我注意到内存消耗显着增加并持续增加,直到达到4GB的最大值,此时应用程序因内存不足错误而崩溃。

PS:在相同的嵌入式 Derby 数据库上运行此精确查询大约需要5分钟,但最终会返回并且DBeaver中的内存使用量保持不变,大约为400mb。 < / p>

1 个答案:

答案 0 :(得分:0)

所有更新的行都会加载到内存中,直到提交。您可以根据主键和LIMIT子句更新块。例如:

 UPDATE TABLE_NAME SET COLUMN1= 0 WHERE COLUMN1 != 0 AND (PK_ID > 1000000 AND PK_ID < 2000000) LIMIT 1000000

以上语句显示了限制行的两种不同技术。首先,通过使用索引列来限制;第二,使用LIMIT在更新了多行后停止更新。

http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_update_statement