2016-07-10 72 views
1

我有一个选择的球队/过滤器,并计算下面的查询有多少协会与它们匹配加快联合查询

select t.name, count(c.id) from teams t 
left join users u on t.id = u.team_id 
left join conversation_users cu on cu.user_id = u.id 
left join conversations c on cu.conversation_id = c.id 
group by t.id 
UNION 
select 'Me', count(cu.id) from conversations c 
left join conversation_users cu on cu.conversation_id = c.id 
where cu.user_id = 'logged in user' 
UNION 
select 'All', count(c.id) from conversations c 
left join apps a on c.app_id = a.id 
where a.id = 'current app' 
UNION 
select 'Unassigned', count(c.id) from conversations c 
left join apps a on c.app_id = a.id 
where a.id = 'current app' and c.user_id is null 

我不是数据库的天才,但是这似乎是一个非常低效/不SCALEABLE做法。有没有更好的方法来完成这一点?

目前大约需要50ms才能在小尺寸的桌子上运行。

我想我可以用这种方法

select 
    count(case when c.started then 1 end) as all, 
    count(case when COALESCE(c.assigned_user_id::text, c.assigned_team_id::text) is null and c.started then 1 end) as unassigned, 
    count(case when c.assigned_user_id = 'clt8ojxvk0000dp2fyvwq126' and c.started then 1 end) as me 
from apps a 
left join conversations c on c.app_id = a.id 
where a.id = 'ASnYW1-RgCl0I' 

非常quickyl取我,所有的和无符号的过滤器(约15毫秒),我能做到的球队类似的东西,并把它们合并起来?

+1

缺少通常的嫌疑人:Postgres版本,表定义。并请定义“小尺寸”。人们认为“小”的程度依数量级而定。 –

回答

1

更改为UNION ALL将是一个显而易见的步骤,但我们没有关于此处涉及多少行的信息,因此很难做出性能判断。

+0

可以有任何地方从100到10000s的谈话。队的数量将在1-10左右 – Tarlen

0

首先,您应该分别运行每个查询以确定其中一个是否正在减慢查询速度。您应该确保on子句中使用的所有列都被索引。

其次(如David所建议),将union s更改为union all s。

可以简化第一查询:

select t.name, count(cu.conversation_id) 
from teams t left join 
    users u 
    on t.id = u.team_id left join 
    conversation_users cu 
    on cu.user_id = u.id 
group by t.name 

据推测,conversation_users是一个结合表,所以每一行指的是一个对话。

同样第二个查询可以简化为删除join S:

select 'Me', count(*) 
from conversation_users cu 
where cu.user_id = 'logged in user' 

最后两个也许能减少到:

select 'All', count(*) 
from conversations c 
where c.app_id = 'current app' 

select 'Unassigned', count(*) 
from conversations c 
where c.app_id = 'current app' and c.user_id is null 

这些变化使(合理的)假设关于数据模型。

此外,你应该考虑改变你的数据模型,所以id是整数,而不是字符串。对按键使用连接会导致较低的性能,但在这种情况下其他因素可能更重要。

+0

这有点帮助,我已经用另一种可能更好的方法更新了帖子 – Tarlen