2012-08-10 67 views
0

有人告訴我,使用加入到優化這個查詢:優化MySQL查詢多個表中,使用VS JOIN(或其他方式)和性能

select distinct p.product_id 
from cart_products p 
    left join product_bikes b on p.product_id = b.product_id where bike_id = $bike_id 
or 
p.product_id in (
    select product_id from cart_product_options where option_id in (
     select option_id from cart_product_option_variants where variant_id in (
      select variant_id from variant_bikes where bike_id=$bike_id 
     ) 
    ) 
) 

然而,使用加入似乎給沒有速度提升可言:

select distinct p.product_id from cart_products p 
    left join product_bikes pb on p.product_id = pb.product_id and pb.bike_id = $bike_id 
    left join cart_product_options po on po.product_id = p.product_id 
    left join cart_product_option_variants pov on pov.option_id = po.option_id 
    left join variant_bikes vb on vb.variant_id = pov.variant_id and vb.bike_id = $bike_id 
    where pb.bike_id = $bike_id or vb.bike_id = $bike_id 

根據服務器的負載電流表大小他們都很快進行,但是當有很多更多的產品,產品的選擇等附加組件的這部分確實導致速度變慢。我只是想知道以什麼方式讓mysql運行這個查詢最快。有人可以說一個事實JOINS是優越的答案或知道任何其他技巧來加速?

+1

您能否驗證JOIN條件和WHERE子句中使用的所有字段是否定義了某種索引? – 2012-08-10 18:21:11

+0

是的,我可以驗證。所有連接條件都在主鍵上,否則索引。主要問題是,即使商店中只有1000件左右的產品,product_bikes和variant_bikes也會有超過100萬行,我們希望有超過10,000件商品。 – Wolfe 2012-08-10 18:21:53

回答

1

Mysql在處理「in」語句中的子查詢方面做得很差。相關子查詢中「存在」的使用速度要快得多,特別是如果內部表中用於關聯的字段有索引。

嘗試類似:

select distinct p.product_id 
from cart_products p left join 
    product_bikes b 
    on p.product_id = b.product_id 
where bike_id = $bike_id or 
     exists (select * 
       from cart_product_options cpo 
       where cpo.productid = p.productid and 
        exists (select option_id 
          from cart_product_option_variants cpov 
          where cpo.option_id = cpov.option_id and 
            exists (select variant_id 
              from variant_bikes vb 
              where vb.variant_id = cpov.variant_id and 
               bike_id=$bike_id 
              ) 
          ) 
      ) 

這應該工作。 。 。但你確實有很多嵌套的子查詢。

+0

謝謝,這個表現會比JOIN更好還是加入最後? – Wolfe 2012-08-10 19:06:29

+1

它應該比「in」表現更好。我懷疑連接版本有創建大量額外的行的問題,因爲表之間的所有連接。換句話說,他們可能都有不好的表現,但出於不同的原因。 – 2012-08-10 19:22:43