现网的一个 sql 慢查询,不是很懂。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
luxinfl
V2EX    程序员

现网的一个 sql 慢查询,不是很懂。

  •  
  •   luxinfl 2022-11-29 14:21:29 +08:00 via Android 2506 次点击
    这是一个创建于 1132 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概是这样,一个积分表 point ,我需要一次查询 100 个用户积分过期 expired 的数据。 表字段大概这样

    字段 类型 索引 pointid varchar primary key expired varchar index userid varchar index 
    select userid from point where now()>= expired oser by id asc limit 0,100 

    我修改成了

    select distinct userid from point a where exists (select userid from point b where a.userid =b.userid and now()>=expired )order by a.userid asc limit 0,100 

    为啥修改后的查询时间要比修改前快了 100 倍,修改前 8s ,修改后 0.07s 。 执行计划,修改前:index rows 约等于 160w 修改后:一个 range ,300 ,using index for group-by ;一个 ref ,16000;

    第 1 条附言    2022-11-30 14:26:23 +08:00
    我发现这玩意还和数据分布有关系,数据比较分散的快都挺慢的,感觉执行计划里面的 rows 不是很准。
    13 条回复    2022-11-30 05:17:29 +08:00
    plutome
        1
    plutome  
       2022-11-29 14:23:56 +08:00
    同不懂
    CEBBCAT
        2
    CEBBCAT  
       2022-11-29 14:28:28 +08:00
    第一个是先过滤出*所有*过期的,然后按照 id (也不知道你说的是哪个 id )排序,然后再取前一百

    后一个是在表上按照 userid 增序遍历,然后过滤出一百个后中止,返回结果

    我建议按照主键遍历,利用 where pointid>${上一批结果中最后一个结果的 ID},来过滤数据
    QKgf555H87Fp0cth
        4
    QKgf555H87Fp0cth  
       2022-11-29 14:42:19 +08:00
    第一条去掉 order by 看看
    eijnix
        5
    eijnix  
       2022-11-29 14:43:36 +08:00
    你是不是用的 mysql 5.6 版本? 如果是的话可能是 mysql 的 order by + limit 的一个坑, 你这里可以把第一个 sql 的 limit 放的很大试试
    前阵子写的: https://juejin.cn/post/7164423778033172517
    luxinfl
        6
    luxinfl  
    OP
       2022-11-29 15:00:44 +08:00
    @CEBBCAT 上一批结果是啥意思。。不过我看这个业务每次找到 100 个用户就行了,两次任务重复了也没关系。。
    luxinfl
        7
    luxinfl  
    OP
       2022-11-29 15:02:32 +08:00
    @likunyan 去掉也慢,而且改动了原来的逻辑,虽然这逻辑没卵用。。。
    simple2025
        8
    simple2025  
       2022-11-29 15:21:54 +08:00
    你这个应该是 order by 的问题吧,第二个是 order by user_id 不是 order by id 了
    simple2025
        9
    simple2025  
       2022-11-29 15:24:05 +08:00
    还有 explain 呢?
    CEBBCAT
        10
    CEBBCAT  
       2022-11-29 15:44:48 +08:00
    @luxinfl
    > 去掉也慢,而且改动了原来的逻辑,虽然这逻辑没卵用。。。
    那直接去掉不就好了,保持最简。

    > 上一批结果是啥意思。。不过我看这个业务每次找到 100 个用户就行了,两次任务重复了也没关系。。
    你不是要分批查询,每次一百个吗?上一批就是上次那 100 个中最后一行的 pointid 。你指定了 pointid ,之前扫描过的行就不会再扫描了。你说的这个“两次任务重复了也没关系”我倒是有点没明白,是查询到了之后会立即做删除,所以下次查询之前表里已经没有这批数据了吗?

    你得想想,怎么让整个任务周期中数据库引擎做尽量少的事。如果你每次都是从表的第一行开始查,那么你执行多少次 SQL ,第一行就得差多少词。这样的复杂度得奔 n^2 去了吧
    luxinfl
        11
    luxinfl  
    OP
       2022-11-29 19:44:22 +08:00
    @chenqh 这个纯属写错了,就是 userid
    luxinfl
        12
    luxinfl  
    OP
       2022-11-29 19:46:36 +08:00
    @CEBBCAT 这个定时任务只负责每次查 100 条满足的用户,貌似是加了锁,不会重复扫描到。。但是我后来又导入一批数据,发现 explain 一样,但是两条 sql 执行结果时间又差不多了。。。搞不懂
    qinrui
        13
    qinrui  
       2022-11-30 05:17:29 +08:00 via iPhone
    在第一句的 where 后面加上 1=1 and 试一下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2988 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 13:42 PVG 21:42 LAX 05:42 JFK 08:42
    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