V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
golangLover
V2EX  ›  Java

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

  •  
  •   golangLover · 2022-03-17 15:34:47 +08:00 · 1387 次点击
    这是一个创建于 775 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    情景 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 的部分交给业务,但可读性好像比较低。大家习惯怎么样子来解决这些查询的问题。

    欢迎赐教。谢谢

    5 条回复    2022-03-18 15:13:27 +08:00
    BiChengfei
        1
    BiChengfei  
       2022-03-17 16:10:41 +08:00
    我主要看有什么现成的方法,没有 byIds() 方法就用 byId()
    实践中,byIds() 的性能会好一点,最简单的原因是 byId() 每次都要写日志,而 byIds() 只用写一次,但只好很少很少。
    健壮、好维护的就是好代码,性能问题等遇到再解决
    golangLover
        2
    golangLover  
    OP
       2022-03-17 16:29:20 +08:00 via Android
    @BiChengfei oracle 的话 in 最多是 1000 个 id 吧,所以 by ids 最多每次也是 1000 个?
    BiChengfei
        3
    BiChengfei  
       2022-03-17 16:48:34 +08:00
    xuanbg
        4
    xuanbg  
       2022-03-18 07:58:39 +08:00
    你如果考虑循环次数的话,就根本不会这么想的好不好。正确的做法是联表查询
    zzfer
        5
    zzfer  
       2022-03-18 15:13:27 +08:00
    一般都是关联查询吧,能一次 sql 查完尽量一次查完吧,减少和数据库交互的次数
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2544 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:00 · PVG 21:00 · LAX 06:00 · JFK 09:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.