问题描述:
数据表: 用户表 500万数据,用户证书表3000万数据
业务场景:查询第三方库判断用户是否有学完某些课程获得证书,没有则给出前去学习的提示。上线时发现没有学习的用户很久都没提示。review团队成员的sql如下,优化前sql执行耗时接近10秒
SELECT
count(1),
b.f_name
FROM
LGQYQ.STD_LGQRLZYJ_T_USER_QL_VIEW a
JOIN LGQYQ.STD_LGQRLZYJ_T_USER_CERTIFICATE_QL_VIEW b ON
a.id = b.f_user_id
WHERE
(a.f_id_card = '445221199905246524'
OR (a.F_NAME = '林某某'
AND a.F_PHONE = '1341xxxx974'))
AND b.f_name IN('a课程', 'b课程')
GROUP BY
b.f_name;
优化后:sql优化后如下,性能优化到0.01秒
select count(1), f_name from LGQYQ.STD_LGQRLZYJ_T_USER_CERTIFICATE_QL_VIEW where f_user_id = (
SELECT id FROM LGQYQ.STD_LGQRLZYJ_T_USER_QL_VIEW where f_id_card = '445221199905246524'
union
SELECT id FROM LGQYQ.STD_LGQRLZYJ_T_USER_QL_VIEW where F_PHONE = '1341xxxx974' AND F_NAME = '林某某')
and f_name IN('a课程', 'b课程') group by f_name
总结
使用explain查看sql执行计划,尽量优化sql走索引,并且在本地加一个字段标记证书学习状态,减少第三方数据库性能波动导致的影响,而且每次查本地库单个状态要比查第三方库的大表要快得多。