背景交代
团队做大学英语四六级考试相关服务。业务中有一个care服务,购买了care服务考试不过可以全额退款,不过有一个前提是要完成care服务的任务,比如坚持背单词N天,完成指定的试卷。
在这个背景下,接到一个需求,需求本身比较复杂,简化出与本篇主题相关的需求是:当2021年6月的四六级考试完成之后,要统计出两种用户数据:
- 完成care服务的用户
- 没有完成care的用户
所以简化的逻辑就是要在所有的用户中区分出care完成用户和care未完成用户。
-
目标1:完成care服务
-
目标2:未完成care服务
所有目标用户的数量在2.7w左右,care完成用户在0.4w左右。所以我需要做的是在从数据库中查询出的 2.7w 所有用户,去另一个表区分出care完成用户和care未完成用户。
说明: 需求本身逻辑有点绕,为了能让读者看明白就最大程度的做了简化,所以看起来就是一个简单的数据库查询问题。同时数据库多表操作首选是连表操作,当时做需求因为逻辑比较复杂并没有想到。感谢读者212的s提醒,我接受批评。所以将本篇当着python数据结构使用来看就可以,数据库查询优化水很深,显然我没把握住。
第一版
第一版:纯粹使用数据库查询。首先查询出所有目标,然后遍历所有用户,在遍历中使用user id从另一张表中查询出care完成用户。
总量在2.7w 左右,所以数据库就查询了2.7w次。
耗时统计:144.7 s
def remind_repurchase():
# 查询出所有用户
all_users = cm.UserPlan.select().where(cm.UserPlan.plan_id.in_([15, 16]))
plan_15_16_not_refund_users = []
plan_15_16_can_refund_users = []
for user in all_users:
# 从另一张表查询用户是否完成care
user_insurance = cm.UserInsurance.select().where(
cm.UserInsurance.user_id == user.user_id,
cm.UserInsurance.plan_id == user.plan_id,
cm.UserInsurance.status == cm.UserInsurance.STATUS_SUCCESS,
)
# care 完成
if len(user_insurance) == 1:
# 其他逻辑
plan_15_16_can_refund_users.append(user.user_id)
else:
# care未完成用户
plan_15_16_not_refund_users