2011-01-26 116 views
1

我试图优化此查询,但可能。在我的测试表中,这也完全符合我的要求,但在实时表上,这需要很长时间才能运行。Oracle/SQL - 需要帮助优化此联合/组/计数查询

select THING_, 
      count(case STATUS_ when '_Good_' then 1 end) as GOOD, 
      count(case STATUS_ when '_Bad_' then 1 end) as BAD, 
      count(case STATUS_ when '_Bad_' then 1 end)/count(case STATUS_ when '_Good_' then 1 end) * 100 as FAIL_PERCENT 
    from  
       (
       select  THING_, 
          STATUS_, 
        from <good table> 
        where TIMESTAMP_ > (sysdate - 1) and 
          STATUS_ = '_Good_' and 
          upper(THING_) like '%TEST%' 

       UNION ALL   

       select  THING_, 
          STATUS_, 
        from <bad table> 
        where TIMESTAMP_ > (sysdate - 1) and 
          STATUS_ = '_Bad_' and 
          THING_THING_ like '%TEST%' 
       ) u 
    group by THING_ 

我想通过查看查询它应该是自我解释什么,我想做的事,但如果没有,或者如果需要额外的信息,请让我知道,我会张贴一些示例表。

谢谢!

+1

是'好桌子'和'坏桌子'真正的桌子,而不是e。 G。视图,嵌套查询等? – Quassnoi 2011-01-26 15:52:35

回答

0

(1)望着执行计划应始终在诊断SQL性能的第一步的问题

(2)书面查询一个可能的问题是,因为SYSDATE是不计算的函数直到执行时间(即确定执行计划之后),优化程序不能利用时间戳列上的直方图来评估索引的效用。我看到这会导致优化器决策不佳。如果你能找出一种方法先计算出日期,然后将它作为一个绑定或一个文字输入到查询中,这可能会有所帮助,但这只是一个猜测。

(3)也许一个更好的整体方式来构建查询将作为每​​个表上的聚合查询之间的连接(可能是完整的外连接)。

SELECT COALESCE(g.thing_,b.thing_), COALESCE(good_count,0), COALESCE(bad_count,0) 
    FROM (SELECT thing_,count(*) good_count from good_table WHERE ... GROUP BY thing_) g 
     FULL OUTER JOIN 
     (SELECT thing_,count(*) bad_count from bad_table WHERE ... GROUP BY thing_) b 
     ON b.thing_ = g.thing_ 

(不得不说,这似乎有点奇怪,你有两个独立的表时,你也有一个状态栏,表示“好”或“坏”的,但也许我过多解释。)

2

在两个表中的(STATUS_, TIMESTAMP_)上创建复合索引。

0

您是否尝试过使用分析函数?它可能会减少一些时间执行。在这里你是一个例子:

select distinct col1, col2, col3 
(Select col1, 
     count(col2) over (partition by col1) col2, 
     count(col3) over (partition by col1) col3 
from table 
) 

这样的事情。