2011-08-30 46 views
2

我試圖實現slope one算法。我有系統在線諮詢,專家可以諮詢用戶。 Expert是type = 2的用戶。而且我需要提供「與這位專家諮詢過的人的諮詢」。對於expert_id1和expert_id2,子查詢返回序列爲0(未查詢),1(查詢)的數組,但該序列由超過100k個值組成,並且此查詢執行速度非常慢。請任何想法來優化此查詢。斜率一種算法,優化查詢

SELECT e1.id as expert_id1, e2.id as expert_id2, 
     (
     SELECT array_accum(c.consulted) FROM (
      SELECT CASE WHEN (c.id is null) THEN 0 ELSE 1 END as consulted 
      FROM co_user u 
      CROSS JOIN user e 
      LEFT JOIN consultation c ON e.id = c.expert_id and c.user_id = u.id 
      WHERE e.type = 2 AND e.id = e1.id) as c 
     ) as expert_id1_consulted, 
     (
     SELECT array_accum(c.consulted) FROM (
      SELECT CASE WHEN (c.id is null) THEN 0 ELSE 1 END as consulted 
      FROM user u 
      CROSS JOIN user e 
      LEFT JOIN consultation c ON e.id = c.expert_id and c.user_id = u.id 
      WHERE e.type = 2 AND e.id = e2.id) as c 
     ) as expert_id2_consulted 
FROM user e1 
CROSS JOIN user e2 
WHERE e1.type = 2 AND 
     e2.type = 2 AND 
     e2.id > e1.id 
ORDER BY e1.id 
+0

你能否更新表結構和一些示例數據的問題? – J0HN

+0

編輯您的問題,並粘貼SQL CREATE TABLE和INSERT語句。很少有人願意從你的查詢中反轉你的表格。 –

+0

也請加解釋分析輸出。 –

回答

0

儘管解釋分析輸出會非常有幫助,但在此查詢中有幾個紅旗。 FWIW我傾向於避免在列列表中選擇子查詢,因爲這可以減少可讀性。

但是在這種情況下,您的子計劃通過潛在的大表創建不必要的連接。

首先要做的是將這些子選詞分解出來。它們使得查詢更難以閱讀和追蹤,並且它們添加了大量重複聯接,這意味着可能對大型表進行額外掃描。例如,您可以將CASE放在array_agg之內等。

如果這不起作用,請發佈解釋分析結果,我們可以從那裏查看索引。