如何做兼顾性能与可维护性的复杂查询?

2022-03-17 15:34:47 +08:00
 golangLover

如果面对复杂的查询应该怎么办

情景 1: 就是可能那个查询的一个表跟另外一个表其实没有建立起外键关系(历史原因,短期内无法改变)

但 A 表跟 B 表之间可以透过一定关系关联起来,例如 A 表的 StoreId, locationId 之类在 B 表也有,理论上只要靠这些特定的字段就能读取到 B 表的某些特别数据(关系可能是一对多)。那大家会怎么做这种关联?在实体上用 JoinColumnOrFormula 吗?

情景 2: 另外也是上面这种延申的情况。两者不能直接用字段组合直接关系起来,要 StoreId+LocationId+(某用户的地址与 B 表的用户地址类近) 才能组合出来。。。 那用 JPA 查询以及实体关联应该怎么写呢。

最后一个问题就是习惯问题。如果我在对 A 表某部分的已经筛选了的数据查询 B 表,我应该是这样(伪代码,没从 IDE 运行过,但大概是这样)

做法 A:

List<DataA> TableARecords = daoA.findByCriteria(....)

List<DataB> dataBList = new ArrayList();

for(dataA in TableARecords){
	List<DataB> bResult = daoB.findBy(dataA.getStoreId);
    dataBList.add(bResult);
}

还是说我应该这样 做法 B

List<DataA> TableARecords = daoA.findByCriteria(....)
List<Integer> storeId = TableARecords.stream().map(e->e->getStoreId).collect(Collectors.toList);

Map<Integer, List<DataB>> mapB= daoB.findByStoreId(storeId).steram().collector(Collectors.groupBy(e->e.getStoreId);


for(dataA in TableARecords){
	Integer id = Optional.ofNullable(mapB.get(dataA.getStoreId)).orElse(null);
    if ( id == null ){
    	return
    }
    
	List<DataB> bResult = mapB.get(id)
    dataBList.add(bResult);
}

我的问题就是应该把这部分 map 的工作尽可能交给 dao 层还是交给业务层呢?上面那个在 for 循环里面查询,怕会把数据库打满或者也比较慢。下面那个就是把数据库连接数减少,但是 map 的部分交给业务,但可读性好像比较低。大家习惯怎么样子来解决这些查询的问题。

欢迎赐教。谢谢

1469 次点击
所在节点    Java
5 条回复
BiChengfei
2022-03-17 16:10:41 +08:00
我主要看有什么现成的方法,没有 byIds() 方法就用 byId()
实践中,byIds() 的性能会好一点,最简单的原因是 byId() 每次都要写日志,而 byIds() 只用写一次,但只好很少很少。
健壮、好维护的就是好代码,性能问题等遇到再解决
golangLover
2022-03-17 16:29:20 +08:00
@BiChengfei oracle 的话 in 最多是 1000 个 id 吧,所以 by ids 最多每次也是 1000 个?
BiChengfei
2022-03-17 16:48:34 +08:00
xuanbg
2022-03-18 07:58:39 +08:00
你如果考虑循环次数的话,就根本不会这么想的好不好。正确的做法是联表查询
zzfer
2022-03-18 15:13:27 +08:00
一般都是关联查询吧,能一次 sql 查完尽量一次查完吧,减少和数据库交互的次数

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

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

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

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

© 2021 V2EX