【发布时间】:2018-04-25 10:29:41
【问题描述】:
我有一个包含相当大实体模型的数据库。 总共有 14 个表,平均记录约 10 万条。
当我测试我的应用程序从数据库中获取一个实体并将其转换为 json 并将其返回给调用者时,需要 7 秒才能获取条目。
这似乎不是初始化问题,因为如果我连续两次执行相同的调用,它们都需要大约 10 秒才能获取数据。
当我启用 sql 脚本日志记录时,我发现对于每个读取的实体,hibernate 都会向数据库发送数百个 sql 请求。 (实际数量基于实体有多少连接/许可证/产品/服务等,但对于我的测试条目,我收到了 286 个查询(总共花费了大约 7 秒)) 当数据库为空时(测试应该返回的数据除外),大约需要 6 秒。
我想问题是因为我将 @OneToMany 和 @ManyToMany 的 fetch 设置为 Lazy,但是当我将它们设置为 Eager 时,我收到多个 fetch bag 的错误。
@javax.persistence.OneToMany(fetch = javax.persistence.FetchType.LAZY)
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.FALSE)
@javax.persistence.JoinColumn(name = "ProductId")
这是我拥有的 OneToMany 关系的一个示例,它模拟了没有多个 fetch bag 错误的 Eager fetch。
这是一个常见问题吗? 以及如何提高阅读速度?
【问题讨论】:
-
您的 JSON 文档有多大,有多少关系? Fetch 类型通常应该是惰性的,但如果您需要阅读世界,那将总是很慢。如果空表中的单个实体需要 6 秒,那么它一定是巨大的!
-
生成的 json 长 2652 行,由来自数据库的总共 502 条记录组成
-
去掉 Hibernate 特有的 LazyCollection 注解,你会得到与便携式 FetchType.EAGER 相同的效果(我一般不推荐)。然后看看有多少查询?你是做 502 次选择,还是有一些选择有很多结果?
-
如果我将获取类型设置为渴望,我会得到一个 MultipleBagFetchException,LazyCollection 注释是解决方案,我不确定是否存在其他解决方案
-
我不想使用急切获取,我建议按照下面的答案使用连接获取或获取图,或者更改批量大小以进行读取。但是,为了做到这一点,我想知道当系统使用延迟获取时有多少个选择以及有多少个表?
标签: java sql-server hibernate spring-data-jpa