Sql 加速联合查询

Sql 加速联合查询,sql,postgresql,Sql,Postgresql,我有下面的查询选择团队/过滤器,并计算有多少关联与之匹配 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', co

我有下面的查询选择团队/过滤器,并计算有多少关联与之匹配

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
我不是数据库天才,但这似乎是一种非常低效/不可扩展的方法。有没有更好的方法来实现这一点

目前,在一个小尺寸的桌子上运行大约需要50毫秒

我想我可以用这种方法很快地获取Me、All和Unsigned过滤器(大约15毫秒)

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'

我可以为团队做一些类似的事情并将它们合并在一起吗?

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

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

其次(按照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\u users
是一个连接表,因此每一行引用一个对话

类似地,可以简化第二个查询以删除
连接
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
这些更改对数据模型做出了(合理的)假设


此外,您应该考虑更改数据模型,以便IDS是整数,而不是字符串。使用连接键会降低性能,但在这种情况下,其他因素可能更为重要。

可以进行100到10000次对话。团队数量将在1-10人左右。通常的嫌疑犯缺失:Postgres版本,表格定义。请定义“小尺寸”。人们对“小”的想象在数量级上是不同的。这有点帮助,我用另一种可能更好的方法更新了这篇文章