2011-10-12 153 views
0

私は継続的にこのような遅いクエリをログに記録するショッピングカートを持っている...MySQLのスロークエリの最適化

# Query_time: 4 Lock_time: 0 Rows_sent: 50 Rows_examined: 454403 
    SELECT SQL_CALC_FOUND_ROWS products.*, 
          descr1.product       AS product, 
          Min(prices.price)      AS price, 
          GROUP_CONCAT(IF(products_categories.link_type = 'M', 
          Concat(products_categories.category_id, 
          'M'), products_categories.category_id)) AS 
          category_ids, 
          cscart_seo_names.name     AS seo_name 
FROM cscart_products AS products 
     LEFT JOIN cscart_product_descriptions AS descr1 
     ON descr1.product_id = products.product_id 
      AND descr1.lang_code = 'EN' 
     LEFT JOIN cscart_product_prices AS prices 
     ON prices.product_id = products.product_id 
      AND prices.lower_limit = 1 
     INNER JOIN cscart_products_categories AS products_categories 
     ON products_categories.product_id = products.product_id 
     INNER JOIN cscart_categories 
     ON cscart_categories.category_id = products_categories.category_id 
      AND (cscart_categories.usergroup_ids = '' 
        OR Find_in_set(0, cscart_categories.usergroup_ids) 
        OR Find_in_set(1, cscart_categories.usergroup_ids)) 
      AND cscart_categories.status IN ('A', 'H') 
     LEFT JOIN cscart_seo_names 
     ON cscart_seo_names.object_id = products.product_id 
      AND cscart_seo_names.TYPE = 'p' 
      AND cscart_seo_names.dispatch = '' 
      AND cscart_seo_names.lang_code = 'EN' 
WHERE 1 
     AND products.company_id = 0 
     AND (products.usergroup_ids = '' 
       OR Find_in_set(0, products.usergroup_ids) 
       OR Find_in_set(1, products.usergroup_ids)) 
     AND products.status IN ('A') 
     AND prices.usergroup_id IN (0, 0, 1) 
GROUP BY products.product_id 
ORDER BY descr1.product ASC 
LIMIT 1300, 50; 

私はこのクエリをスピードアップする方法についてカートの会社から任意の助けを得るように見えることはできません。多分インデックスを追加する必要がありますか?私は確信が持たれておらず、この問題を解決するための正しい方向で私を指摘する助けを得たいと思っています。

おかげで、

クリス・エドワーズ私は遅さの原因となることができ、このクエリの問題の多くを見る

+0

'EXPLAIN'はあなたの親友です – meze

答えて

1

...すべての

まず、どこでもあなたは「FIND_IN_SET」を使用している、してみてください代わりにINを使用します。

cscart_categories.usergroup_ids = '' 
OR FIND_IN_SET(0, cscart_categories.usergroup_ids) 
OR FIND_IN_SET(1, cscart_categories.usergroup_ids) 

は次のようになります:

それ以外
cscart_categories.usergroup_ids IN ('', '0', '1') 

、で使用されているすべての列が参加していることを確認し、グループごとに「OR」条件では、インデックスを使用することができますを除去することにより、 where節、またはorderingが索引付けされます。

もう1つの提案は、 'GROUP_CONCAT'を削除し、その情報を別のクエリで個別に選択することです。

+0

あなたは間違っています。あなたの提案は同等ではありません。 – Karolis

+0

最初の部分がうまくいきません... IN関数はFIND_IN_SET関数の代わりに機能しません。私が知っているこれを最適化する他の唯一の方法は、OR条件を削除し、それぞれの条件に対してUNIONSを使用することです。 – Seth