请教 MySql 多表 join 怎么优化好

2021-10-13 10:38:45 +08:00
 MozzieW

接到一个不确定+复杂的需求(对我而言),背景是: 现在后台有一个用户表 user ( id,orderId),会员订单表 order(id,type,expireTime),用户每日登录日志表 log(id,uid,createdAt);表的行数基本在 100 万(订单表 10 万)。 现在需要可能是:

  1. 找到最近 10 天登录的用户
  2. 或者,最近 10 天登录的会员用户(根据有没有订单 id )
  3. 或者,最近 10 天登录的过期会员用户 ...others 根据条件拿到用户 id 去做其他任务,就是条件可能不一样。
    根据我仅有的 MySql 知识和这两天的 Google,我试了一下实现是,
select user.*, order.*, max(log.createdAt) from user
join order on user.orderId = order.id -- 如果要过期用户,这里加一个 expireTime 判断
join log on log.uid = user.id and log.createdAt > '2021-10-01 00:00:00'
group by user.id -- 这是配合 join log on 获取最新登录一次的时间

现在我的问题是:

  1. 各位大佬遇到这种需求是不是这样的,如果需求增加或变了再调整 sql 的拼接(好像无法实现一个大的逻辑去嵌套小的条件适应需求变化?)
  2. 这里一共需要三个表 join,我造了 100 万行的数据测试,发现执行一次大概要 15 秒左右。查了资料,看到说不要用 join,或者根据让小表驱动大表,建索引等操作,这些都在试(学);不过还是问一下大佬有没有建议?
3650 次点击
所在节点    MySQL
22 条回复
MozzieW
2021-10-14 11:20:31 +08:00
@lldld 现在的测试数据里用户表 700 万条,订单表 10 万,日志表 150 万(后面这个表会增加比较快)。
你给的先 select distinct 应该是有效的,但是和我另外用的 where 优化貌似冲突了。
因为给的表和实际不一样(我去掉了多余的字段),而且我昨天发完贴优化的时候,试了一下最后用 where 过滤 user,这样才得到 3 秒的结果(因为这里最大的耗时是 join 导致的,而且最后的 where 需要在 join 之后计算,按照 join on where 的执行顺序我理解加 where 是会在 join 之后增加更多时间);实际是加了 where 之后结果集少了,同时时间也变少了,3 秒多;不加 where 需要大概 7 秒甚至更高;而你给的 select distinct 可以做到 5 秒,但是加上 where 后时间又涨回去了( 7 秒)。
我猜测 where+join 可能是把 user 表的条件先做优化,减少 user 表参与 join 的行数;而用 log 做主表后这个 where 的优化没有了,而 logged 的行数已经比 user 通过 where 的行数多,从而导致时间增加。
clancyliu
2021-10-15 01:01:36 +08:00
根据之前各位大佬提示,我的想法是,在用户表中增加最后一次登录时间 last_login_time,是否会员标致 vip_flag,会员过期时间 vip_expire_time, 每次登录更新 last_login_time, 下单就置 vip_flag 为 1,且更新 vip_expire_time 。你提到的三个问题,都能通过查一张表解决如下:
1. select * from user where last_login_time >= 10 天前
2. select * from user where vip_flag = 1 and last_login_time >= 10 天前
3. select * from user where vip_flag = 1 and last_login_time >= 10 天前 and vip_expire_tima > 现在
再添加相应索引,应该能够一定的优化效果。
上面说到的是对新来的数据的处理,老的数据也可以通过登录日志表和订单表把新增的三个字段赋值上(洗数据),不知道这样能不能对你有一些帮助。

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

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

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

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

© 2021 V2EX