sql中相似条件统计的优化

536 阅读1分钟

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的统计结果集,然后进行关联。 本人工作中的该问题,优化前直接死锁,优化后几乎是秒查。