加速缓慢的MySQL SubQuery更新

时间:2013-02-27 18:38:32

标签: mysql performance subquery

我有以下UPDATE脚本,它保留了我网站上活动产品的数量,因此我可以快速参考该类别是否有产品而不在前端进行此计数。

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 个答案:

答案 0 :(得分:3)

如果要更新很多行,那么进行连接可能会更有效,而不是使用“嵌套循环”操作。

   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)