mysql 查询历史用户的疑问? - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
Grocker

mysql 查询历史用户的疑问?

  •  
  •   Grocker Apr 23, 2023 2108 views
    This topic created in 1123 days ago, the information mentioned may be changed or developed.

    表 t

    uid status
    1 1
    2 2
    1 2
    1 3
    2 3

    查询只存在 status=1 的用户,这两种写法有什么区别吗

    SELECT * FROM t where `status` = 1 and uid not IN ( SELECT uid FROM t as t1 WHERE `status` in (2,3) and t.uid = t1.uid ) 
    SELECT * FROM t where `status` = 1 and uid not IN ( SELECT uid FROM t as t1 WHERE `status` in (2,3) ) 

    场景是查历史用户,即 status != 2,3 的,以上是简化的模型,两个字段都有索引

    上面的多了一个子查询和外表的条件,在表数据量大的情况下性能谁更好,leader 说第一种查询效率会更高,因为它只在满足外表的条件下进行了过滤。或者有没有其他性能更好的写法?

    8 replies    2023-04-24 14:20:15 +08:00
    kkwa56188
        1
    kkwa56188  
       Apr 23, 2023
    不是做 Mysql 的, 感觉是 1 比较快.
    其次 用 in (value1, value2) 通常是很慢的, 索引不一定管用.

    我会换成:
    SELECT * FROM t where t.status = 1
    and not exists ( SELECT uid FROM t as t1 WHERE status = 2 and t1.uid = t.uid )
    and not exists ( SELECT uid FROM t as t2 WHERE t2.status = 3 and t2.uid = t.uid )
    joetse
        2
    joetse  
       Apr 23, 2023 via iPhone
    为什么不用 bitmap?
    akira
        3
    akira  
       Apr 23, 2023   1
    status 区分度这么低,再来个 not in ,性能不好上来吧。试试这么考虑呢,虽然是有点取巧了

    select uid, min(status) `mins`, max(status) `maxs`
    from t
    group by uid
    having `mins` = 1 and `maxs` = 1
    512357301
        4
    512357301  
       Apr 23, 2023 via Android
    用 group by 呢?
    select
    uid,
    sum(if(status = 1,1,0)) one_cnt,
    sum(if(status = 2 or status = 3,1,0)) other_cnt
    from t
    group by uid
    having one_cnt > 0 and other_cnt = 0

    没在机器上测试,反正我下意识的写法是这么写,楼主可以测试下。

    PS:对楼主和楼上各位的子查询写法感觉很别扭,我一直用不惯子查询嵌套,更习惯 left join ,不过 mysql 出身的貌似都这么写,存在即是合理,我不争辩。
    xuanbg
        5
    xuanbg  
       Apr 24, 2023
    我会写成这样:
    with have23 as (SELECT uid FROM t as t1 WHERE `status` in (2,3))
    select * from t left join have23 h on h.uid = t.uid where h.uid is null;
    Grocker
        6
    Grocker  
    OP
       Apr 24, 2023
    @akira 实际场景是有 4 种状态,ABCD ,存在 AB 且没有 CD 状态的用户
    Grocker
        7
    Grocker  
    OP
       Apr 24, 2023
    @xuanbg 忘了说了是 mysql5.7
    akira
        8
    akira  
       Apr 24, 2023
    @Grocker 那就分别对 4 个状态做统计,思路是一样的
    About     Help     Advertise     Blog     API     FAQ     Solana     3204 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 44ms UTC 12:10 PVG 20:10 LAX 05:10 JFK 08:10
    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