如何做兼顾性能与可维护性的复杂查询? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
golangLover
V2EX    Java

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

  •  
  •   golangLover Mar 17, 2022 1900 views
    This topic created in 1501 days ago, the information mentioned may be changed or developed.

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

    情景 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 replies    2022-03-18 15:13:27 +08:00
    BiChengfei
        1
    BiChengfei  
       Mar 17, 2022
    我主要看有什么现成的方法,没有 byIds() 方法就用 byId()
    实践中,byIds() 的性能会好一点,最简单的原因是 byId() 每次都要写日志,而 byIds() 只用写一次,但只好很少很少。
    健壮、好维护的就是好代码,性能问题等遇到再解决
    golangLover
        2
    golangLover  
    OP
       Mar 17, 2022 via Android
    @BiChengfei oracle 的话 in 最多是 1000 个 id 吧,所以 by ids 最多每次也是 1000 个?
    BiChengfei
        3
    BiChengfei  
       Mar 17, 2022
    xuanbg
        4
    xuanbg  
       Mar 18, 2022
    你如果考虑循环次数的话,就根本不会这么想的好不好。正确的做法是联表查询
    zzfer
        5
    zzfer  
       Mar 18, 2022
    一般都是关联查询吧,能一次 sql 查完尽量一次查完吧,减少和数据库交互的次数
    About     Help     Advertise     Blog     API     FAQ     Solana     1070 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 23:26 PVG 07:26 LAX 16:26 JFK 19:26
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86