Oracle / SQL - 需要帮助优化此union / group / count查询

时间:2011-01-26 15:48:53

标签: sql oracle group-by union

我正在尝试优化此查询。在我的测试表中,这也完全符合我的要求,但在实时表中,这需要很长时间才能运行。

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_ 

我认为通过查看查询,我应该自我解释我想要做什么,但如果没有,或者如果需要其他信息,请告诉我,我会发布一些示例表。

谢谢!

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

您是否尝试使用分析功能?它可能会减少执行时间。这是一个例子:

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

就像那样。

答案 2 :(得分: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_

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