将多个NOT IN转换为LEFT JOIN以提高性能

时间:2015-09-23 06:47:54

标签: mysql sql

我有这个SQL查询需要很长时间才能执行。

SELECT DISTINCT p.products_id, 
                p.products_group, 
                p.products_quantity, 
                p.products_length, 
                p.products_price, 
                p.products_height, 
                p.products_width, 
                p.products_weight, 
                p.products_cost, 
                p.products_rmb_cost, 
                p.products_best_rmb, 
                p.products_status, 
                p.products_image, 
                p.products_vendor_code, 
                p.products_date_added, 
                pd.products_name 
FROM   products p, 
       products_description pd 
WHERE  p.products_id = pd.products_id 
       AND p.products_id NOT IN(SELECT related_products_id 
                                FROM   products_related 
                                WHERE  products_id = '93667') 
       AND p.products_id NOT IN(SELECT products_id 
                                FROM   products_related 
                                WHERE  related_products_id = '93667') 
       AND p.products_group = '300' 
       AND language_id = 1 
       AND ( ( ( pd.products_name LIKE '%emerald%' ) 
                OR p.products_image LIKE '%emerald%' 
                OR p.products_id LIKE '%emerald%' ) 
             AND ( ( pd.products_name LIKE '%square%' ) 
                    OR p.products_image LIKE '%square%' 
                    OR p.products_id LIKE '%square%' ) ) 
       AND pd.products_id != '93667' 
ORDER  BY p.products_group, 
          p.products_quantity, 
          p.products_id 

我试图将2 NOT IN部分转换为LEFT JOIN而不是改善性能,但我虽然性能确实大幅提升,但我得到的结果与原始查询不同。 有关如何正确修改此查询以使用LEFT JOIN而不是NOT IN的任何建议吗?

修改

这是我尝试过的,但结果不对:

SELECT DISTINCT p.products_id, 
                p.products_group, 
                p.products_quantity, 
                p.products_length, 
                p.products_price, 
                p.products_height, 
                p.products_width, 
                p.products_weight, 
                p.products_cost, 
                p.products_rmb_cost, 
                p.products_best_rmb, 
                p.products_status, 
                p.products_image, 
                p.products_vendor_code, 
                p.products_date_added, 
                pd.products_name 
FROM   products p, 
       products_description pd 
       LEFT JOIN products_related pr 
              ON pr.products_id = '93667' 
                 AND pr.related_products_id = '93667' 
WHERE  p.products_id = pd.products_id 
       AND pr.products_id IS NULL 
       AND pr.related_products_id IS NULL 
       AND p.products_group = '300' 
       AND language_id = 1 
       AND ( ( ( pd.products_name LIKE '%emerald%' ) 
                OR p.products_image LIKE '%emerald%' 
                OR p.products_id LIKE '%emerald%' ) 
             AND ( ( pd.products_name LIKE '%square%' ) 
                    OR p.products_image LIKE '%square%' 
                    OR p.products_id LIKE '%square%' ) ) 
       AND pd.products_id != '93667' 
ORDER  BY p.products_group, 
          p.products_quantity, 
          p.products_id 

1 个答案:

答案 0 :(得分:1)

尝试以下转换后的查询到左连接 -

SELECT DISTINCT p.products_id, 
                p.products_group, 
                p.products_quantity, 
                p.products_length, 
                p.products_price, 
                p.products_height, 
                p.products_width, 
                p.products_weight, 
                p.products_cost, 
                p.products_rmb_cost, 
                p.products_best_rmb, 
                p.products_status, 
                p.products_image, 
                p.products_vendor_code, 
                p.products_date_added, 
                pd.products_name 
FROM   products p  
JOIN products_description pd ON p.products_id = pd.products_id 
LEFT JOIN products_related pr1 ON p.products_id=pr1.related_products_id AND pr1.products_id = '93667'
LEFT JOIN products_related pr2 ON p.products_id=pr2.products_id AND pr2.related_products_id = '93667'
WHERE  p.products_group = '300' 
       AND language_id = 1 
       AND ( ( ( pd.products_name LIKE '%emerald%' ) 
                OR p.products_image LIKE '%emerald%' 
                OR p.products_id LIKE '%emerald%' ) 
             AND ( ( pd.products_name LIKE '%square%' ) 
                    OR p.products_image LIKE '%square%' 
                    OR p.products_id LIKE '%square%' ) ) 
       AND pd.products_id != '93667' 
       AND pr1.related_products_id IS NULL 
       AND pr2.products_id IS NULL 
ORDER  BY p.products_group, 
          p.products_quantity, 
          p.products_id