我在扩展使用视图的基于 h2 的 Java 应用程序时遇到问题

Posted

技术标签:

【中文标题】我在扩展使用视图的基于 h2 的 Java 应用程序时遇到问题【英文标题】:I am having trouble scaling my h2 based java app that is using views 【发布时间】:2012-04-17 09:09:28 【问题描述】:

这里是环境: 我们为客户编写了一个基于嵌入式 h2 数据库的应用程序,在进行测试之前它已升级到最新版本。 该数据库由 29 个表和 26 个视图组成。在 26 个视图中,只有 8 个在 java 中真正“使用”,映射视图休眠到 pojos。其他视图只是为其他视图进行背景计算,例如聚合一些值,然后按某些列分组。 在这些视图中进行了大量计算。我们决定不使用 java 进行计算,因为您可以使用自己喜欢的工具(例如 h2 控制台)轻松检查数据库表,看看计算中是否有任何错误。由于这个事实,这些视图中有很多“CASE WHEN ... END”语句,因为一旦该行中的单个列为 NULL,hibernate 总是在所有列中返回具有 NULL 值的整行。我们也无法解决这个问题……然而,由于我们在计算中也有除法,所以无论如何我们都需要检查 NULL、0 和 0.0。 视图是“堆叠的”,因为有时会在其他地方使用一些中间值。但是总是有一个“堆栈”的 7 个视图“下方”一个最终视图也基于另一个使用 6 个视图的“堆栈”的视图。有些观点相同有些不同。

现在问题来了: 当在“有趣”表中将一对(如 20 条)记录插入数据库时​​,一个视图会在大约400 毫秒。这对我们来说没问题。 将数据扩展到大约 500-2000 条记录,特殊视图(交付大约 25 个聚合行)需要一个多小时 (1h) 来交付数据。 该机器是具有 8GB RAM(-Xmx2G 和 -Xms1G)CPU 2.66GHz(Intel(R) Core(TM)2 Quad CPU Q8400 @ 2.66GHz)的 Linux 或具有 4GB RAM (-Xmx1G - Xms512m) CPU 未知,但可能是单核/双核 @ 2GHz。

到目前为止我的分析: 我跟踪了应用程序的内存使用情况,这似乎不是主要问题。 在长时间运行的查询期间查看堆栈跟踪显示,我的堆栈深度(有时)高达 100 级以下(!)我进入休眠 getEntityManager().createQuery(getCriteriaQuery()).getResultList() 的入口点。明显的“耗时”是 org.h2.table.TableFilter/Table/TableView.getBestPlanItem 和 org.h2.table.Plan.calculateCost 以及 org.h2.index.ViewIndex.getCost 。 我检查了所有视图中的所有连接是否缺少索引,找到一个,添加一个,没有成功。

我的测试: 我将所有数据和模式转移到同一台 Linux 机器上的 PostgreSQL (8.1) 中(vanilla 未调整)并在那里运行测试(在进行任何 vaccuum 或 reindex 之前!),结果是压倒性的:大约。 6 秒。使用相同数据的相同视图在 h2 上花费了大约 1 小时。

现在我真的不想切换我的数据库,但这将是最终的选择,除非有人有一个好主意......

备注: 我发现的事情如下: 在查看 h2 的 information_schema 中的视图时,我可以看到他正在做很多工作来分析视图本身。 我的 sql 脚本中的所有视图都在 20 到 120 行之间(大约)。信息模式中的“编译”视图范围从 2KBytes 到 3MBytes(即兆字节),上面的视图接近 400k ... 也许这也是问题的一部分......

好的,这就是所有的人。我很乐意提供任何帮助。我愿意切换数据库,因为我们到处都在使用 hibernate 和 CriteriaQuery,所以唯一的工作就是切换 jdbc 连接器,更改视图中的一些代码(已经完成,但必须在生产前检查两次)并安装PostgreSQL 或客户台式机 (irk) 上的 MSDE,这会导致可能发生的其他不需要的错误,因为 MS 更新可能会使 MSDE 损坏或由于任何原因数据库无法启动...

问候, 霍尔格

【问题讨论】:

【参考方案1】:

也许查询/视图太复杂,H2 无法对其进行优化,但如果不知道细节(重现问题的代码)就很难说。 PostgreSQL 的优化器优于 H2 优化器。可能您需要创建其他索引。为了分析这一点,我建议阅读有关performance optimizations and indexes的文档。

【讨论】:

以上是关于我在扩展使用视图的基于 h2 的 Java 应用程序时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

配置嵌入式 H2 用户以进行分发

glassfish 和 h2database 问题

如何使用具有自定义文件扩展名的 H2 数据库?

恢复 h2 数据库

在 h2 中创建枢轴

内存数据库中的 H2:使用 JDBC 设置时区? Java 单元测试