我为用户及其请求提供了一个简单的数据模型:
User
- id,
- name
Request
- id,
- createdAt,
- completedAt,
- status
- userId (FK to user)
我正在尝试运行一个查询,为每个用户收集一些统计信息。问题是我必须运行相同的子查询来获取我选择的每个参数的用户请求。相反,我想运行一次,然后计算一些统计数据。
select
u.id as UserId,
(select count(*)
from Requests r
where userId = u.id
and timestamp > @dateFrom) as Total,
(select count(*)
from Requests r
where userId = u.id
and timestamp > @dateFrom
and status = N'Completed') as Completed,
(select status
from Requests r
where userId = u.id
and timestamp > @dateFrom
and status != N'Completed') as ActiveStatus,
(select datediff(second, createdAt, completedAt)
from Requests r
where userId = u.id
and timestamp > @dateFrom
and status == N'Completed') as AvgProcessingTime
from User u
显然,这个查询非常慢,我需要优化它。我试过加入,申请,排名,对我来说没有任何效果(因为我无法完成所有必需统计数据的查询)。
从性能角度来看,这里最好的方法是什么?
答案 0 :(得分:1)
使用左连接和聚合
尝试此操作这里可能有几个问题,但让我知道你是怎么回事。
select
u.id as UserId
,count(r.UserId) [Total]
,sum(iif(r.status = N'Completed',1,0)) [Completed]
,sum(iif(r.status <> N'Completed',1,0)) [ActiveStatus]
,avg(iif(r.status = N'Completed', datediff(second, createdAt, completedAt),0)) [AvgProcessingTime]
from User u
left join Request R
where timestamp > @datefrom
and r.userId = u.id
group by
u.id
答案 1 :(得分:1)
我不确定这个查询是因为我没有在我的机器上运行它,但你可以尝试一下,如果需要也可以做一些改变 -
Collectors.groupingBy