MySQL查询运行*非常*慢

时间:2012-11-30 15:27:29

标签: mysql sql performance

我有一个运行速度非常慢的SQL查询,我很困惑为什么。查询是:

SELECT DISTINCT(c.ID),c.* FROM `content` c 
  LEFT JOIN `content_meta` cm1 ON c.id =    cm1.content_id 
 WHERE 1=1 
   AND c.site_id IN (14) 
   AND c.type IN ('a','t') 
   AND c.status = 'visible' 
   AND (c.lock = 0 OR c.site_id = 14) 
   AND c.level = 0 
    OR 
       (
          (     c.site_id = 14 
            AND cm1.meta_key = 'g_id' 
            AND cm1.meta_value IN ('12','13','7')
          ) 
          OR 
          (     c.status = 'visible' 
            AND ( 
                    (c.type = 'topic' AND c.parent_id IN (628,633,624))
                )
          )
       ) 
 ORDER BY c.date_updated DESC LIMIT 20

内容表有大约1250行,内容元表有大约3000行。这不是很多数据,我不太确定是什么导致它运行这么慢。任何想法/意见将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

你的条款是否正确?您正在制作一系列AND语句,之后您正在执行OR。

不正确的是:

AND (c.lock = 0 OR c.site_id = 14) 
AND (
        ( ... )
        OR
        ( ... )
   )

如果它确实是正确的,您可以考虑更改结构或在脚本或过程中处理结果。

答案 1 :(得分:0)

最后可能与你的“OR”子句有关...你的前面的索引尽可能被索引使用,但是你可以在最后输入这个巨大的OR条件另一个。不知道更多的底层内容,我会调整内部有一个UNION,这样每个实体都可以利用自己的索引,获得合格的CID,然后加入最终结果。

select
      c2.*
   from
      ( select distinct
              c.ID
           from
              `content` c
           where
                  c.site_id in (14)
              and c.type in ('a', 't' )
              and c.status = 'visible'
              and c.lock in ( 0, 14 )
              and c.level = 0
        UNION
        select
              c.ID
           from
              `content` c
           where
                  c.status = 'visible'
              and c.type = 'topic'
              and c.parent_id in ( 628, 633, 624 )
        UNION
        select
              c.ID
           from
              `content` c
                 join `content_meta` cm1
                    on c.id = cm1.content_id
                   AND cm1.meta_key = 'g_id'
                   AND cm1.meta_value in ( '12', '13', '7' )
           where        
                  c.site_id = 14 ) PreQuery
      JOIN `content` c2
         on PreQuery.cID = c2.cID
   order by
      c2.date_updated desc
   limit
      20

我会确保内容表在(site_id,type,status)上有另一个索引(parent_id,type,status)

和元表,(content_id,meta_key,meta_value)上的索引