2016-07-10 71 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