java - Hibernate 为每个查询生成不同的 SQL

标签 java sql performance hibernate memory-leaks

我刚刚在分析器下测试了我的应用程序,发现 sql 字符串占用了我大约 30% 的内存!这很奇怪。

有很多这样的字符串存储在应用程序内存中。这是 hibernate 生成的 SQL 查询,注意不同的数字和结尾的下划线:

select avatardata0_.Id as Id4305_0_,...... where avatardata0_.Id=? for update
select avatardata0_.Id as Id4347_0_,...... where avatardata0_.Id=? for update

这是我无法理解的部分。为什么hibernate必须为每个查询生成具有不同标识符的不同sql字符串,例如“Id4305_0_”?为什么它不能对所有相同的查询使用一个查询字符串?这是绕过查询缓存的某种技巧吗?

如果有人能描述我为什么会发生这种情况以及如何避免这种资源浪费,我将不胜感激。

更新

好的。我找到了。假设内存泄漏我错了,这是我的错。 Hibernate 正在按预期工作。

我的应用在 10 个线程中创建了 121(!) 个 SessionFactories,它们产生了大约 2300 个 SingleTableEntityPersisters 实例。每个 SingleTableEntityPersister 都会生成大约 15 个具有不同标识符的 SQL 查询。 Hibernate 被迫生成大约 345.000 个不同的 SQL 查询。一切都很好,没有什么奇怪的:)

最佳答案

hibernate 生成的查询字符串背后有一个逻辑。其主要目的是获取表和列名称的唯一别名。

根据您的查询,

select avatardata0_.Id as Id4305_0_,...... where avatardata0_.Id=?

avatardata0_ ==> avatardata is the alias of the table and 0_ is appended to indicate it is the first table in the query. So if it were the second table(or Entity) in the query it should have been shown as avatardata1_. It uses the same logic for the column aliases.

所以,这样就避免了所有可能的冲突。

您看到这些查询是因为您打开了配置的 show_sql 标志。 这用于调试查询。一旦您的应用程序开始工作,您应该将其关闭。

阅读有关 API 文档的更多信息 here .

我不太了解内存消耗部分,但是您在关闭上述标志的情况下重复测试,看看是否有任何改进。

关于java - Hibernate 为每个查询生成不同的 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9452183/

相关文章:

java - 如何在 linux shell 脚本中添加 java 类文件夹而不是 jar

java - 将 Map<Enum, Enum> 存储为字符串

MySQL 正则表达式语句

sql - 在 Oracle SQL 中对数据集进行分组

performance - MongoDB 在计算空值时非常慢(或 {$exists : false})

java - 通过 java 将文件从 Linux 服务器中的一个位置复制到另一个位置的最佳方法

java - 如何从循环语句内的用户获取字符串或整数数组?

sql - ORDER BY 在 CASE 表达式中有两个条件

java - 对于 boolean 值,(p ^ q) 和 (p != q) 之间是否存在有用的区别?

performance - Excel/VBA 检查一行是否存在