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

2022-11-29 14:21:29 +08:00
 luxinfl

大概是这样,一个积分表 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;

2138 次点击
所在节点    程序员
13 条回复
plutome
2022-11-29 14:23:56 +08:00
同不懂
CEBBCAT
2022-11-29 14:28:28 +08:00
第一个是先过滤出*所有*过期的,然后按照 id (也不知道你说的是哪个 id )排序,然后再取前一百

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

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

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

你得想想,怎么让整个任务周期中数据库引擎做尽量少的事。如果你每次都是从表的第一行开始查,那么你执行多少次 SQL ,第一行就得差多少词。这样的复杂度得奔 n^2 去了吧
luxinfl
2022-11-29 19:44:22 +08:00
@chenqh 这个纯属写错了,就是 userid
luxinfl
2022-11-29 19:46:36 +08:00
@CEBBCAT 这个定时任务只负责每次查 100 条满足的用户,貌似是加了锁,不会重复扫描到。。但是我后来又导入一批数据,发现 explain 一样,但是两条 sql 执行结果时间又差不多了。。。搞不懂
qinrui
2022-11-30 05:17:29 +08:00
在第一句的 where 后面加上 1=1 and 试一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/898787

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX