1

我有一个运行非常缓慢的 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 行。这不是很多数据,我不太确定是什么导致它运行如此缓慢。任何想法/意见将不胜感激。

谢谢!

4

2 回答 2

1

你的where子句正确吗?您正在执行一系列 AND 语句,然后您正在执行 OR。

正确的不是这样的:

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

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

于 2012-11-30T16:13:32.013 回答
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 )上的索引

于 2012-11-30T16:23:01.510 回答