2011-08-30 54 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之内等。

如果这不起作用,请发布解释分析结果,我们可以从那里查看索引。