这个SQL语句是否需要重构?

时间:2009-10-28 05:21:57

标签: sql oracle oracle9i performance

SELECT DISTINCT group_id
       , supplier_id
       , supplier_name
       , site_division_id
       , site_division_name 
FROM view_supplier_site 
WHERE supplier_id IN (SELECT DISTINCT supplier_id 
                      FROM view_supplier 
                      WHERE YEAR IN (2008, 2009) 
                      AND received_quantity > 0 
                      AND COE_SUPPLIER NOT IN ('X - LG', 'Y - LG', 'Z - LG') ) 

2 个答案:

答案 0 :(得分:4)

非子查询因子:

  SELECT vss.group_id, 
         vss.supplier_id, 
         vss.supplier_name, 
         vss.site_division_id, 
         vss.site_division_name 
    FROM view_supplier_site vss
    JOIN (SELECT vs.supplier_id
            FROM view_supplier vs
           WHERE vs.year IN (2008, 2009)  
             AND vs.received_quantity > 0 
             AND vs.coe_supplier NOT IN ('X - LG', 'Y - LG', 'Z - LG')
        GROUP BY vs.supplier_id) s ON s.supplier_id = vss.supplier_id
GROUP BY vss.group_id, vss.supplier_id, vss.supplier_name, vss.site_division_id, vss.site_division_name 

使用子查询分解:

WITH suppliers AS (
    SELECT vs.supplier_id
      FROM view_supplier vs
     WHERE vs.year IN (2008, 2009)  
       AND vs.received_quantity > 0 
       AND vs.coe_supplier NOT IN ('X - LG', 'Y - LG', 'Z - LG')
  GROUP BY vs.supplier_id)
  SELECT vss.group_id, 
         vss.supplier_id, 
         vss.supplier_name, 
         vss.site_division_id, 
         vss.site_division_name 
    FROM view_supplier_site vss
    JOIN suppliers s ON s.supplier_id = vss.supplier_id
GROUP BY vss.group_id, vss.supplier_id, vss.supplier_name, vss.site_division_id, vss.site_division_name 

他们是等同的。

我可以看到,没有太多的优化。接下来要看的是索引......

答案 1 :(得分:1)

我建议如下:

  • 不使用n IN,而是使用内部联接(可能不是性能改进,但语句看起来“更好”)
  • 这将允许您摆脱view_supplier上的DISTINCT(再次,可能没有性能差异)
  • 是否需要view_supplier上的DISTINCT?有些ID可能是supplier_site的关键。
  • NOT IN可能是性能问题..您可以将此更改为<'X - LG'左右的其他内容吗?
  • 如果视图不仅仅是基表/列的“别名”,则可能有使用基础表的方法。
  • 要看的另一件事是索引。
  • YEAR是计算列吗?如果只是YEAR(datevalue),使用datevalue between <Jan1st> and <Dec31>
  • 之类的内容可能会更快

这些变化大部分都是装饰性的,关注的方面取决于你在陈述中看到的问题。