如何优化这个需要很长时间的查询。

时间:2014-02-18 07:36:20

标签: php mysql sql

在mysql上使用以下查询时,它执行大约10秒。

   SELECT SQL_CALC_FOUND_ROWS DISTINCT
          b.appearance_id,
          b.photo_album_id,
          b.eventcmmnt_id,
          b.id,
          b.mem_id,
          b.subj, 
          b.body,
          b.image_link as photo_image_uploaded,
          b.bottle_id,
          b.date, 
          b.parentid, 
          b.from_id, 
          b.visible_to,
          pa.photo_big as image_link,
          b.post_via,
          b.youtubeLink,
          b.link_image,
          b.link_url,
          b.auto_genrate_text,
          badges.badge_img,
          badges.badge_bottle_img,
          b.type,b.share_url_title
     FROM bulletin b 
          INNER JOIN network n 
                     ON (n.mem_id = b.mem_id) 
          LEFT JOIN badges 
                     ON (b.bottle_id=badges.badge_id) 
          LEFT JOIN photo_album as pa 
                    ON (pa.photo_id=b.photo_album_id) 
          JOIN members mem
                    ON (b.mem_id=mem.mem_id and mem.deleted<>'Y') 
    WHERE b.parentid = '0'
          AND ('$userid' IN (n.frd_id, b.mem_id,b.from_id)) 
 GROUP BY b.id 
 ORDER BY b.id DESC 
    LIMIT 0,10

IN约束内的内部查询有很多frd_id,mem_id,from_id所以我认为因为上面的查询执行缓慢...所以请帮助优化上面的查询

由于

2 个答案:

答案 0 :(得分:0)

检查您是否在字段上有索引,用于连接。

答案 1 :(得分:0)

正如您已经暗示的那样,发布查询的EXPLAIN SELECT...计划。为什么猜你什么时候可以检查? (而且一个SQL小提琴也很棒)。

这将告诉您是否需要索引(非常非常可能!)以及哪些索引以及结构如何(去索引所有内容,因为这甚至可能会损害性能!)。

我已经可以给出一个建议:如果您在表单members上有索引字段

(mem_id, deleted, ...)

如您所知,确认deleted确实是boolean(如果不是,请将其转换为{Y}和'N'的enum,并指定这样的条件:

on(b.mem_id=mem.mem_id AND NOT mem.deleted)

因为这在索引上会更容易。如果该字段不是布尔值,例如它可能具有'待定'的值'Y','N'和'P',并且您使用了varchar字段,那么<>对指数有相当大的性能影响 - 我甚至会说道,并指出该指数有效中和。索引最适合匹配,而不是不匹配 <>

我怀疑你也可以重新设计这个表达式

AND ('$userid' IN (n.frd_id, b.mem_id,b.from_id)) 

b JOIN中移动它,尽管是部分移动。或者您可以考虑使用UNION代替表格的基数。