如何优化这个complected查询?

时间:2014-01-20 07:32:32

标签: mysql sql performance select query-optimization

在mysql上使用以下查询时,它被锁定了,

SELECT event_list.* 
FROM event_list 
    INNER JOIN members 
        ON members.profilenam=event_list.even_loc 
WHERE (even_own IN (SELECT frd_id 
                    FROM network 
                    WHERE mem_id='911' 
                    GROUP BY frd_id) 
           OR even_own = '911' ) 
       AND event_list.even_active = 'y' 
GROUP BY event_list.even_id 
ORDER BY event_list.even_stat ASC

IN约束内的内部查询有很多frd_id,所以因为上面的查询是slooow ...,所以请帮忙。

感谢。

4 个答案:

答案 0 :(得分:0)

内部查询不需要GROUP BY,这将使数据库引擎做很多不必要的工作。

答案 1 :(得分:0)

如果您将even_own = '911'放在select from network之前,那么如果even_own IS 911则不必执行子查询。 另外,为什么子查询上有group by

同时运行explain plan顶部找出花费时间的内容。

答案 2 :(得分:0)

试试这个:

SELECT el.* 
FROM event_list el 
INNER JOIN members m ON m.profilenam = el.even_loc 
WHERE el.even_active = 'y' AND 
     (el.even_own = 911 OR EXISTS (SELECT 1 FROM network n WHERE n.mem_id=911 AND n.frd_id = el.even_own))       
GROUP BY el.even_id 
ORDER BY el.even_stat ASC

答案 3 :(得分:0)

这可能会更好:

      ( SELECT  e.*
            FROM  event_list AS e
            INNER JOIN  members AS m ON m.profilenam = e.even_loc
            JOIN  network AS n ON e.even_own = n.frd_id
            WHERE  n.mem_id = '911'
              AND  e.even_active = 'y'
            ORDER BY  e.even_stat ASC )
    UNION  DISTINCT 
      ( SELECT  e.*
            FROM  event_list AS e
            INNER JOIN  members AS m ON m.profilenam = e.even_loc
            WHERE  e.even_own = '911'
              AND  e.even_active = 'y' )
    ORDER BY  e.even_stat ASC

由于我不知道JOIN是一对多(或什么),我投入DISTINCT以避免重复。可能有更好的方法,或者可能没有必要(即UNION ALL)。

请注意我如何避免两种性能杀手:

  • 或 - 变成UNION
  • IN(SELECT ...) - 变成了JOIN。

我制作别名以减少混乱。我将ORDER BY移到UNION之外(并添加了parens以使其正常工作)。