Java Hibernate 复杂实体关联下,简单查询都很慢,如何优化?

325 天前
 XiaoJiang9527

最近正在整改一个老项目,里面的表结构错综复杂,实体中的映射表字段基本都增加了 @ManyToOne 和 @JoinColumn 注解,导致很多简单单表查询都需要执行很久。 但是打印具体 hibernate SQL 日志,Explain 下,也不存在什么性能问题,各位大佬们,怎么解?

5728 次点击
所在节点    程序员
65 条回复
nothingistrue
323 天前
@yidinghe #55 你可以再深入一点,什么 Mybatis ,什么 Service ,什么 Controller 都是多余的,再继续一点什么前端框架也是多余的—— 原生 javascript + SQL 就够了。
nothingistrue
323 天前
@Nosub #56 作者信息,是「文章」的属性,它来自于「用户」,但与「用户」不存在实体关联关系。换个更直白的说法,文章的作者姓名,跟用户的名称,通过用户 ID 能映射,但他们不是同一个值。如果再仔细看,用户名称可变更,但作者姓名是不可变更的,它们连等值映射都做不了。你的实体关联关系是错误的。

请注意,上面说的是实体关联关系,即 Entity-Relation ,这是数据库设计的概要模型阶段,与 ORM 、DDD 都没关系。

当把 ER 弄明白之后,在看「查询文章列表,其中要带上作者信息」这个查询,那就根本不存在任何性能问题,因为这是单表查询。当然这个不是没有其他付出的,需要额外处理「文章」的 userId 、authorName 、authorAvatar ,跟 「用户」的 id 、name 、avatar 之间的一致性问题。不过这个原本就是之前漏掉的业务功能,严格的说也不算是额外付出。处理起来也不是那么麻烦:
Post.userId - User.id 这是不变量,只需要自然保存即可;
Post.authorName - User.name ,实际业务上,这里已经是不相干的俩属性了,根本无需同步,如果功能上设计成需要同步的,见下面 avatar 的同步处理;
Post.authorAvatar - User.avatar ,需要 User 修改 avatar 的时候,利用观察者模式、或者事件模式,让 Post (以及其他任何对此修改感兴趣的实体)连带去修改 authorAvatar (不过,如果 avatar 是实时图片的话,那么不如把 Avatar 也独立成单独实体,Post 、User 都只存不可变的 avatarId ,前端显示/数据导出的时候,再根据 avatarId 去实时获取最新图片);
UBcai
323 天前
@TGhoull 看来是我没写清楚,我没说 hibernate 拉。hibernate 有学习成本,然后架构其实也不怎么会,他就是还没确定入职,想简单一点,导致了后面的一系列问题。然后还有个问题,很多甲方公司有 dba ,都是禁止外键,我们项目每次改的 sql 都用 flyway 记录版本,到甲方服务器根本更新不了。你敢信,每次更新我全部都是手动运行 sql ,手动改 flyway 版本状态。人都麻了
INCerry
323 天前
是什么数据库? mysql 之类的多表查性能本来就很差
stone981023655
128 天前
@UBcai 就是熟练度不高

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1013581

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX