2011-10-12 93 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代替。通过在条件去掉“OR”,索引可以使用:

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') 

除此之外,确保每一个正在被使用的柱联接,GROUP BY子句,where子句或排序进行索引。

另一个建议是删除'GROUP_CONCAT'并在另一个查询中单独选择该信息。

+0

你错了。你的建议不是等同的。 – Karolis

+0

你说得对第一部分不工作... IN函数将不起作用,而不是FIND_IN_SET函数。我知道的唯一另一种优化方法是删除OR条件,并针对每个条件使用UNION。 – Seth