0

次の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)'が、これは、動作する更新によって影響を受けた可能性のあるカテゴリを特定することを意味しますが、素敵な天才の誰かが私が逃したより良い解決策を持っているかどうか疑問に思いましたか?

前もって感謝します。

4

1 に答える 1

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)
于 2013-02-27T19:06:11.917 に答える