簡體   English   中英

優化同一張表的多個子查詢

[英]optimize multiple sub queries for same table

我有一個查詢,其中同一個表上有多個子查詢。 我嘗試將它們轉換為左連接,但這比此查詢花費的時間更多。

有問題的表是:product_class_link

如果有人可以幫助我解決任何問題,那就太好了。

提前致謝

select pc.id as id,
       pc.code,
       pc.name,
       pc.deliver_from,
       pc.delivery,
       pc.is_active,
       1 as results,
       cr.ship_date_advance, 
       p.callouts, 
       p.coid,
       p.c_name, 
       pc.start_expire_date, 
       pc.end_expire_date
from product_collection pc
join (select p.product_collection_id, 
             pdc.id as coid, pdc.name as c_name,
             count(distinct pcl.product_id) as callouts, pi.quantity
      from product p
      join product_color pclr on pclr.product_id=p.id 
      join product_collection pc on pc.id=p.product_collection_id and pc.client_id = 142 and pc.active='True'
      left join product_gender_link pgl on pgl.product_id=p.id
      left join product_callout_link pcl on pcl.product_collection_id=pc.id and pcl.product_id=p.id
      left join product_callout pdc on pdc.id=pcl.product_callout_id and pdc.client_id=142
      left join product_inventory pi on pi.product_color_id=pclr.id and pi.quantity>0 
      left join product_price_link ppl on ppl.product_id=p.id
      LEFT JOIN product_class_link pdcl ON pdcl.product_id = p.id
      where ppl.product_price_id in (447,249,456) 
      and p.active = 'True'
      and pgl.product_gender_id = 411
      AND ( ( product_sub_class_id = 10 AND pdcl.product_id IN ( select DISTINCT product_id 
                                                                 FROM product_class_link 
                                                                 WHERE  product_sub_class_id = 51 
                                                                 OR  product_sub_class_id = 53 
                                                                 OR  product_sub_class_id = 55 
                                                                 ) 
            )  
            OR  ( product_sub_class_id = 11 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 OR  product_sub_class_id = 55 )  )  
            OR  ( product_sub_class_id = 12 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 OR  product_sub_class_id = 53 OR  product_sub_class_id = 55 )  )  
            OR  ( product_sub_class_id = 14 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 OR  product_sub_class_id = 52 OR  product_sub_class_id = 55 )  )  
            OR  ( product_sub_class_id = 13 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 ))  
            OR  ( product_sub_class_id = 15 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 OR  product_sub_class_id = 52 OR  product_sub_class_id = 55 )  )  
            OR  ( product_sub_class_id = 24 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            OR  ( product_sub_class_id = 29 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            OR  ( product_sub_class_id = 25 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            OR  ( product_sub_class_id = 30 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            OR  ( product_sub_class_id = 20 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            OR  ( product_sub_class_id = 23 AND pdcl.product_id IN (select DISTINCT product_id FROM product_class_link WHERE  product_sub_class_id = 51 )  )  
            )
        and (pc.is_active < 2 or pi.quantity IS NOT NULL)
        group by pc.id, pdc.id
      ) as p on p.product_collection_id=pc.id
left join client_shipdate_rules cr on cr.product_collection_id=pc.id
where  pc.active='True'
and pc.client_id = 142
group by pc.id, p.coid
order by pc.position,pc.name, pc.deliver_from, p.coid

這是解釋查詢的 output:

1   PRIMARY pc  
    NULL
    ref PRIMARY,product_collection_client,active    active  1   const   32  100.00  Using where; Using temporary; Using filesort    
1   PRIMARY cr  
    NULL
    eq_ref  PRIMARY PRIMARY 4   db148189_atonce_1_4.pc.id   1   100.00  
    NULL
    
1   PRIMARY <derived2>  
    NULL
    ref <auto_key0> <auto_key0> 4   db148189_atonce_1_4.pc.id   106 100.00  
    NULL
    
2   DERIVED pgl 
    NULL
    ref PRIMARY,product_id,product_gender_id    product_gender_id   2   const   1704864 100.00  Using where; Using index; Using temporary; Using filesort   
2   DERIVED p   
    NULL
    eq_ref  PRIMARY,product_collection,active   PRIMARY 4   db148189_atonce_1_4.pgl.product_id  1   50.00   Using where 
2   DERIVED pc  
    NULL
    eq_ref  PRIMARY,product_collection_client,is_active,active  PRIMARY 4   db148189_atonce_1_4.p.product_collection_id 1   6.75    Using where 
2   DERIVED pclr    
    NULL
    ref product_color_ui01,product_code_unique,product_color_product    product_color_product   4   db148189_atonce_1_4.pgl.product_id  1   100.00  Using index 
2   DERIVED pcl 
    NULL
    ref product_collection_id,product_id    product_id  8   db148189_atonce_1_4.pgl.product_id,db148189_atonce_1_4.p.product_collection_id  1   100.00  Using index 
2   DERIVED pdc 
    NULL
    eq_ref  PRIMARY PRIMARY 4   db148189_atonce_1_4.pcl.product_callout_id  1   100.00  Using where 
2   DERIVED pi  
    NULL
    ref product_color_id,qUANITY_PRODUCT_COLOR_ID   product_color_id    4   db148189_atonce_1_4.pclr.id 2   17.30   Using where 
2   DERIVED ppl 
    NULL
    ref PRIMARY,product_id  product_id  4   db148189_atonce_1_4.pgl.product_id  3   30.00   Using where; Using index    
2   DERIVED pdcl    
    NULL
    ref product_id_2,product_sub_class_id,product_id    product_id_2    5   db148189_atonce_1_4.pgl.product_id  2   68.53   Using where; Using index    
14  DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
13  DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
12  DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
11  DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
10  DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
9   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
8   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    5   func    2   9.52    Using where; Using index    
7   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    10  func,const  1   100.00  Using where; Using index    
6   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    5   func    2   9.52    Using where; Using index    
5   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    5   func    2   9.85    Using where; Using index    
4   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    5   func    2   9.51    Using where; Using index    
3   DEPENDENT SUBQUERY  product_class_link  
    NULL
    index_subquery  product_id_2,product_sub_class_id,product_id    product_id_2    5   func    2   9.85    Using where; Using index    

OR難以優化; 看看你能不能避免它。

IN ( SELECT... ) is usually bad for performance. It can sometimes be turned into a IN ( SELECT... ) is usually bad for performance. It can sometimes be turned into a JOIN or EXISTS(SELECT...) . This is especially valid since you have . This is especially valid since you have DISTINCT`。

看看您是否可以將其從WHERE移出並移入JOIN

   SELECT  DISTINCT product_id
                FROM  product_class_link
                WHERE  product_sub_class_id = 51 )

其中一些索引可能會有所幫助:

PC:   INDEX(active, client_id, id)
cr:   INDEX(product_collection_id,  ship_date_advance)
pcl:  INDEX(product_collection_id,  product_id, product_callout_id)
pi:   INDEX(quantity, product_color_id)
pclr: INDEX(product_id,  id)
PC:   INDEX(is_active, id,  client_id, active)
pgl:  INDEX(product_gender_id, product_id)
ppl:  INDEX(product_price_id, product_id)
pdcl: INDEX(product_id)

警告:由於一些別名用於多個表,以上可能是“錯誤的”。 (例如p

product_sub_class_id在哪個表中?

如果您不需要LEFT ,請不要說出來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM