请教一下,在 node 后端里面大量通过 Promise.all 来查询数据库有什么影响吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coldmonkeybit
V2EX    Node.js

请教一下,在 node 后端里面大量通过 Promise.all 来查询数据库有什么影响吗

  •  
  •   coldmonkeybit 2022 年 11 月 25 日 6944 次点击
    这是一个创建于 1231 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个新项目用 node 做后端,前段时间看到一个删除接口需要操作三张表,大概长这样:

    async delete(){ await order.delete(); await item.delete(); await history.delete(); } 

    然后这个时候从前端调用接口响应时间差不多是 600ms (测试库部署在良心云的便宜实例 docker 上所以比较慢)
    由于这几个调用之间没有关联,所以尝试了一下使用 Promise.all() 来提交:

    async delete(){ const asyncRes = await Promise.all([ order.delete(), item.delete(), history.delete(), ]) } 

    然后发现响应时间居然直接变成 180ms 了,居然快了这么多。
    所以想着有时间就把所有类似的没有关联的请求都换成 all(),但不知道有没有什么大的影响

    18 条回复    2022-11-27 20:52:02 +08:00
    iwh718
        1
    iwh718  
       2022 年 11 月 25 日 via Android
    并发吧。
    coderxy
        2
    coderxy  
       2022 年 11 月 25 日
    正确的用法就是这样
    ysc3839
        3
    ysc3839  
       2022 年 11 月 25 日
    await 的话是按顺序执行,一个完成后执行下一个。Promise.all 是同时执行三个,然后等三个都完成。如果没有顺序要求的话是没问题的。
    star7th
        4
    star7th  
       2022 年 11 月 25 日
    没啥不良影响,你可以这么用。
    第一种 await 的方式顺序执行,一个执行完成再执行另一个。
    第二种方式是,并发执行,等到最后一个结果执行完毕后,再按顺序返回执行结果数据。

    一个是顺序执行,一个是并发执行,当然快了很多。
    coldmonkeybit
        5
    coldmonkeybit  
    OP
       2022 年 11 月 25 日
    @ysc3839 对,我就是想到这点,但就是怕有什么我不知道的地方,才上来确认下,谢谢了。
    coldmonkeybit
        6
    coldmonkeybit  
    OP
       2022 年 11 月 25 日
    @star7th 明白了,谢谢
    pkoukk
        7
    pkoukk  
       2022 年 11 月 25 日   1
    不太一样,业务也许可以接受 order 删除了,item 没有成功删除
    但不一定能接受 item 删除了,order 没有成功删除
    得看你的业务,这种非幂等行为最好还是丢在同个事务里执行
    coldmonkeybit
        8
    coldmonkeybit  
    OP
       2022 年 11 月 25 日
    @pkoukk 确实,不过假如场景换成查询的话,这种并发的模式感觉挺好用,比多个表关联查询要省事很多,适合我这种不是一上来就做后端的哈哈
    makelove
        9
    makelove  
       2022 年 11 月 25 日
    印象中 mysql 一个 connection 并不能并发查询,因为它并不线程安全
    除非你每个查询都用了不同的 connection ,但这样怎么做事务?
    gouflv
        10
    gouflv  
       2022 年 11 月 25 日 via iPhone
    不需要事务的话,随便
    ysc3839
        11
    ysc3839  
       2022 年 11 月 25 日
    @makelove 连接库会有处理的吧?假如不支持并发的话,await 的时候另一个请求来了,又去操作数据库,不就出问题了?
    ETiV
        12
    ETiV  
       2022 年 11 月 25 日
    可以考虑用 async.queue 控制下并发。

    因为你在访问数据库,所以如果并发量没控制好的话,数据库很容易就被你打卦、成单点故障了。。
    zhennann
        13
    zhennann  
       2022 年 11 月 25 日
    1. 如果不考虑事务的话,每个 sql 语句的执行都是从连接池中取一个可用的连接,执行完后又把连接释放,并放回连接池。所以,如果并发语句太多,仍然会等待
    2. 如果 QPS 少的话,在代码内部使用 Promise.all 可以充分利用连接池。如果 QPS 多的话,Promise.all 价值就不大了。因为连接池总是有限的,不是在这等待,就是在那等待
    3. 因此,在业务开发中,考虑到要实现的代码逻辑比较多,都用 Promise.all 做优化,性价比就不高了,还是以提高开发效率优先吧
    stimw
        15
    stimw  
       2022 年 11 月 26 日 via iPhone
    @stimw 说明一下,这个提问和楼主问题是有区别的。只有第三个回答( 51 票那个),以及第四个回答的评论区,是跟楼主问题相关的。
    stevezhang
        16
    stevezhang  
       2022 年 11 月 26 日
    all 你其中有失败的操作不就寄了
    zyronon
        17
    zyronon  
       2022 年 11 月 26 日   1
    用 Promise.allSettled()才能拿到所有返回值
    chenzhe
        18
    chenzhe  
    PRO
       2022 年 11 月 27 日
    @zyronon 学习到了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3240 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 12:26 PVG 20:26 LAX 05:26 JFK 08: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