2011-01-26 142 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 
) 

這樣的事情。