1. 原sql
select
u.id,
u.name,
(select count(1) from t_user_log t
where t.log_date >= '2021-10-01' and <= '2021-10-03' and t.user_id = u.id) as num,
(select count(1) from t_user_log t
where t.log_date >= '2021-10-01' and <= '2021-10-03' and t.user_id = u.id and t.type = 1) as appNum,
(select count(1) from t_user_log t
where t.log_date >= '2021-10-01' and <= '2021-10-03' and t.user_id = u.id and t.type = 2) as pcNum
from t_user u
2. 性能分析
t_user表用户不超过10000条,所以查询起来效率可以 子查询需要查询t_user_log表统计,且需要为每一个t_user的结果集数据查询,所以效率比较低,而且还有3个查询相同表类似统计的子查询,效率会相当低。本人实际工作中,就遇到该种查询,即使对t_user_log再进行索引相关的优化,效率依然很低,且容易死锁。
3. 优化方法
select
u.id,
u.name,
nvl(l.num, 0) as num,
nvl(l.appNum, 0) as appNum,
nvl(l.pcNum, 0) as pcNum
from t_user u
left join (
select
count(1) as num,
sum(decode(t.type, 1, 1, 0)) as appNum,
sum(decode(t.type, 2, 1, 0)) as pcNum,
from t_user_log t
where t.log_date >= '2021-10-01' and <= '2021-10-03'
group by t.user_id
) l on u.id = t.user_id
4. 优化结果
原sql是查询出t_user结果集后,对结果集进行子查询。 优化后sql是查询出t_user结果集和t_user_log的统计结果集,然后进行关联。 本人工作中的该问题,优化前直接死锁,优化后几乎是秒查。