2013-02-27 42 views
0

我有以下更新腳本,它保留了我網站上活動產品的計數,因此如果類別中包含產品或沒有在前端進行此計數,我可以快速參考。使用加快緩慢的MySQL子查詢更新

UPDATE category_to_store 
SET products = (
       SELECT COUNT(*) 
       FROM product p 
       LEFT JOIN product_to_category p2c 
        ON (p.product_id = p2c.product_id) 
       LEFT JOIN product_to_store p2s 
        ON (p.product_id = p2s.product_id) 
       WHERE p.status = '1' 
       AND p.date_available <= NOW() 
       AND p2c.category_id = category_to_store.category_id 
       AND p2s.store_id = category_to_store.store_id 
       ); 

我的表說明如下:

DESCRIBE category_to_store; 

Field  Type  Null Key  Default Extra 
---------------+---------------+-------+-------+-------+--------------- 
category_id int(11)  NO PRI  
store_id int(11)  NO PRI  
products int(11)  NO  0 

DESCRIBE product; 

Field  Type  Null Key  Default Extra 
---------------+---------------+-------+-------+-------+--------------- 
product_id int(11)  NO PRI  auto_increment 
~ 
date_available date  NO   
~ 
status  tinyint(1) NO  0    
~ 

DESCRIBE product_to_category; 

Field  Type  Null Key  Default Extra 
---------------+---------------+-------+-------+-------+--------------- 
product_id int(11) NO PRI  
category_id int(11) NO PRI  

DESCRIBE product_to_store; 

Field  Type  Null Key  Default Extra 
---------------+---------------+-------+-------+-------+--------------- 
product_id int(11) NO PRI  
store_id int(11) NO PRI 0 

product表中有我沒有包含的字段未使用)

這個目前運行正常,但需要花費110目前秒。

我已將網站設置爲使用WHERE category_to_store.category_id = '(int)'來限制查詢,但這意味着計算哪些類別可能會受到更新的影響,我猜想,但我想知道您的任何可愛天才是否有更好的解決方案我已經錯過了?

預先感謝您。

+1

我認爲它比p.date_available <= NOW()更慢。你能檢查這個查詢需要多長時間嗎? – Slowcoder 2013-02-27 18:47:25

+0

將有助於看到解釋的結果... – AllInOne 2013-02-27 19:39:09

+0

spencer7593的解決方案已完美運作。 在產品表中爲'status'和'date_available'添加一個索引可以最初提高速度,但是使用LEFT JOIN完美無缺! – 2013-02-28 12:35:57

回答

2

如果要更新很多行,則執行連接可能更有效,而不是使用「嵌套循環」操作。

UPDATE category_to_store cts 
    LEFT 
    JOIN (
      SELECT COUNT(*) AS cnt_ 
       , p2c.category_id 
       , p2s.store_id 
       FROM product p 
       LEFT 
       JOIN product_to_category p2c 
       ON (p.product_id = p2c.product_id) 
       LEFT 
       JOIN product_to_store p2s 
       ON (p.product_id = p2s.product_id) 
      WHERE p.status = '1' 
       AND p.date_available <= NOW() 
      GROUP 
       BY p2c.category_id 
       , p2s.store_id 
     ) c 
     ON c.category_id = cts.category_id 
     AND c.store_id = cts.store_id 
     SET cts.products = IFNULL(c.cnt_,0) 

爲了獲得最佳性能,你需要合適的指標可用,您可能要考慮例如添加索引

... ON product (product_id, status, date_available) 
+0

spencer7593,你是英雄! 現在運行在不到一秒鐘! 非常感謝! 在UPDATE中使用連接...我仍然有一個很多要學習清楚! – 2013-02-28 12:33:29

+0

我只是剛剛登錄(儘管使用該網站多年),所以沒有足夠高的「聲譽」來upvote這個答案。我會盡我所能! – 2013-02-28 12:39:57