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条件をスローします。基礎となるコンテンツの詳細がわからないため、各エンティティが独自のインデックスを利用し、修飾された CID を取得し、最終結果に結合できるように、内部に UNION を配置するように調整します。

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 に答える