Java 用于永不更改表的最佳Spring/Hibernate配置

Java 用于永不更改表的最佳Spring/Hibernate配置,java,mysql,performance,hibernate,spring,Java,Mysql,Performance,Hibernate,Spring,我目前正在使用Spring+Hibernate+MySQL进行一个项目。我意识到a有相当多的桌子永远不会改变。它们是静态的,不能在这些表上进行插入或更新,因此可以认为是不可变的。对这些表的所有访问都是通过延迟加载实体集合和hql查询来实现的(可以使其成为即时的) 我想知道在这种情况下,处理这种情况的最佳性能方法是什么。我已经准备好了基础知识,只读ehcache、查询缓存和设置为只读的事务(这对Mysql有任何作用吗?)。我还能看什么?哪种隔离模式、传播模式最好?我应该看看其他缓存解决方案吗?或者

我目前正在使用Spring+Hibernate+MySQL进行一个项目。我意识到a有相当多的桌子永远不会改变。它们是静态的,不能在这些表上进行插入或更新,因此可以认为是不可变的。对这些表的所有访问都是通过延迟加载实体集合和hql查询来实现的(可以使其成为即时的)

我想知道在这种情况下,处理这种情况的最佳性能方法是什么。我已经准备好了基础知识,只读ehcache、查询缓存和设置为只读的事务(这对Mysql有任何作用吗?)。我还能看什么?哪种隔离模式、传播模式最好?我应该看看其他缓存解决方案吗?或者我应该简单地消除所有这些,只需将数据加载到一系列hashmap中(希望这将是最后的手段)

另一个可能的(牵强的?)解决方案是使用一些内存中/无事务数据库,并让hibernate连接到它。是否存在这样的数据库引擎


我很感激你们的指点和经验

我以前就已经处理过这类事情了,枚举表中的数据是不变的,坦率地说,最简单的方法就是将表设置为“急切加载”并使用它。除非表非常大,否则从其他任何方面得到的优化都相对较小。不要不屑一顾,但你最好把时间花在优化系统的另一部分上


这样说,如果表特别大,你可能想考虑另一种方法来取消它们包含的数据;如果表数据很大并且从不真正改变,那么您可能想考虑使用Hibernate以外的另一种填充对象树的方法;只需为枚举创建一个类并自己管理该引用的关联(即不使用Hibernate)可能会有所帮助。

根据我的经验,这些类型的表需要从数据库中删除并转换为枚举或其他类型。不是因为性能,而是因为可维护性。信不信由你,与编写脚本来更改生产数据库中的数据相比,更改代码(在我的经验中也是如此)是一种更直接、更简单的操作。特别是如果你不一定自己控制数据库;如果您的公司甚至无法控制它,则更是如此。

为所有实体设置二级cahce(查看hibernate文档了解缓存的各种配置/映射详细信息),配置查询缓存并在映射/使用只读会话中将其标记为不可变,这将使hibernate在执行“事务性写后”和会话刷新时不会检查这些实体的修改

这是一个非常常见的场景,这是您应该做的所有事情。 您不必推出自己的内存hashmap缓存(像Ecache这样的二级缓存为您提供了几种存储替代方案),二级缓存将为您提供这些功能。
无事务数据库访问不会为您提供任何性能方面的服务,因此我不会担心它,让hibernate来处理它。

我认为只读事务是hibernate的优化。如果Hibernate知道不必弄清楚您是否更改了对象中的任何内容,它可以放弃一系列步骤(修改类的CGLib?)

我想您的大多数其他问题都得到了回答。但是,就隔离级别而言,如果从未插入或更新表,则可以使用READ_UNCOMMITTED隔离级别,该级别允许脏读、不可重复读和幻象读。然而,这些都无关紧要,因为数据永远不会改变

您可以在SpringJavadocs()中查看不同的隔离级别及其效果


这将最大限度地释放行上的锁,并将为您提供最佳性能,至少在锁定过程中是如此。

如果表参与RI约束,这可能是一个问题。你将委托给你的应用程序什么是数据库处理得最好的。这些表是否连接到其他确实发生变化的表?是的,确实如此。这正是为什么利基·林赛的解决方案在这种情况下是不可行的,正如你正确指出的。每个答案都提供了一些很好的信息,所以感谢大家!这是我使用的方法,效果很好。您还应该配置查询缓存。纯二级缓存仅在通过id访问实体时有效。要缓存静态表中的“select*”,需要使用查询缓存。