我的查询需要很长时间才能完成

时间:2011-10-06 18:04:46

标签: sql performance oracle

我有一个在Oracle中需要很长时间才能完成的查询。在我杀了之前它跑了几个小时。有什么办法可以加快速度吗?

这是我的问题:

select distinct(random_selection.randnum), 
    random_selection.dropper_id, 
    random_selection.ozip3 
from random_selection 
where random_selection.dropper_id is not null 
and random_selection.quarter = 121
and (random_selection.dropper_id, random_selection.randnum, random_selection.quarter) in 
    (select forecast_entry.dropper, forecast_entry.rand_num, production_weeks.yyq 
    from forecast_entry, production_weeks 
    where forecast_entry.week = production_weeks.production_week 
    and production_weeks.project_cd = 'EXFC' 
    and production_weeks.yyq >= 121)

union 

select distinct(random_selection.randnum), 
    dropper_city_brk_2.dropper_id, 
    random_selection.ozip3 
from random_selection, dropper_city_brk_2, dropper 
where random_selection.ozip3 = dropper_city_brk_2.zip3 
and dropper.dropper_id = dropper_city_brk_2.dropper_id 
and dropper.active = 1 
and dropper_city_brk_2.dropper_id <> 10002 
and random_selection.quarter = 121
and random_selection.dropper_id is null 
and (random_selection.dropper_id, random_selection.randnum, random_selection.quarter) in 
    (select forecast_entry.dropper, forecast_entry.rand_num, production_weeks.yyq 
    from forecast_entry, production_weeks 
    where forecast_entry.week = production_weeks.production_week 
    and production_weeks.project_cd = 'EXFC' 
    and production_weeks.yyq >= 121)

查询解释:

主要目标是从random_selection表中获取所有randnum,dropper_id和ozip3,这些表不在forecast_entry表中,并且位于yyq 121中,项目代码为EXFC。通过关联周和生产周,从production_weeks表中检索yyq。一些dropper_id为null所以我们需要通过关联ozip3和zip3从dropper_city_brk_2表中提取该数据。我们不希望dropper_id处于非活动状态,因此它们必须具有活动等于1,这是通过关联滴管表。

希望这会有所帮助

1 个答案:

答案 0 :(得分:1)

我同意评论者的意见,你应该至少提供一个要点的解释输出,否则很难提供帮助。

您正在运行forecast_entry,production_weeks子查询两次。通过使用CREATE TEMPORARY TABLE计算该查询一次,可以获得更好的性能。

您正在使用“其中X in(子查询)”,这通常不如进行连接。您可以在我刚才建议的临时表上进行INNER JOIN,而不是在这里使用IN子句。

如果您可以容忍重复项或者您知道没有重复项,则可以切换到UNION ALL。 UNION ALL需要的工作量少于UNION。

最后,你可以把它分成三块并分别测试。这些部分是子查询和您正在联合的两个查询。这可能会帮助您缩小哪些部分很慢。