2011-10-12 94 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