java - 使用 JPA 解决 N+1 查询问题时的问题
问题描述
先决条件
我有以下数据库结构:
- 表列表包括 A、B、C、D 和 E
- 所有这些表都有一个 BIGINT 主键
- 表 A 代表基本实体
- 表 B、C 和 D 包含表 A 的外键,本质上是从 A 创建 1:N 关系
- 表 E 有一个外键引用表 D,即表 D 的 1:N 关系
- 所有外键都被索引
问题描述
这里的目标是能够在给定几个文件管理器的情况下使用 JPA 获取具有所有引用实体的基本实体where
。
以前,我依赖于 OSIV 过滤器。因此,在查询时,正在查询没有被引用实体的基本实体,并且在视图层,当 Jackson 尝试访问 getter 以制定响应时,正在执行额外的查询以获取引用的实体。如您所见,这导致了所谓的 N+1 查询问题。此外,作为基本查询的一部分,为分页设置了偏移量和限制。
为了解决 N+1 查询问题,同时确保分页发生在数据库级别而不是应用程序级别的内存中,我执行了以下操作:
- 执行的第一个查询是从表 A 中检索与过滤器匹配的不同 id,按参数排序,并进行分页。
select distinct id from A
left join B on B.a_id = A.id
left join C on C.a_id = A.id
left join D on D.a_id = A.id
left join E on E.d_id = D.id
where A.attribute_1 = ? and B.attribute_2 = ? ...
- 执行的第二个查询是检索完整的 JPA 实体 A,其中包括所有引用的实体,其中 id 是从查询 1 中检索到的 id 之一
select * from A
left outer join B on B.a_id = A.id
left outer join C on C.a_id = A.id
left outer join D on D.a_id = A.id
left outer join E on E.d_id = D.id
where A.id in (:ids)
问题
我面临的问题是发布此优化后,令人惊讶的是性能已显着下降。需要注意的是,查询#2 会导致性能下降。一个观察结果是,随着 C 中的条目增加,查询 #2 正在进一步减慢。过去有没有人遇到过类似的问题,或者如果我做错了什么,请帮助让我知道解决方案。
解决方案
推荐阅读
- hazelcast - Hazelcast IMap 在等待中转条目时会阻塞吗?
- php - 同步同一 MySQL 数据库中不同表的两行
- amazon-web-services - Google Directory User put api throwing 400 错误(无效输入:[SSO])
- sql - 根据同一表上的组合行值更新列
- excel - 基于先前单元格的条件格式,同时跳过空单元格
- nginx - 从 nginx 迁移到 Netlify 或 Github 页面
- excel - 将文件数据抓取到 PSOObject 并按 LastWriteTime 排序的代码
- java - DestroyJavaVM 内存泄漏
- html - 试图理解浮动和文本
- python - 如何修复“AttributeError:'module'对象没有属性'x'”?