下面是使用的数据脚本。
create table enab_test (ban varchar2(10),DVR_IND char(1));
create table oms_test (ban varchar2(10),DVR_IND char(1));
insert into enab_test values('111111111','Y');
insert into enab_test values('123456789','N');
insert into enab_test values('321654987','N');
insert into enab_test values('444444444','Y');
insert into enab_test values('111111111','Y');
insert into enab_test values('741258963','Y');
insert into oms_test values('111111111','Y');
insert into oms_test values('222222222','N');
insert into oms_test values('333333333','N');
insert into oms_test values('444444444','N');
insert into oms_test values('555555555','Y');
insert into oms_test values('666666666','N');
在这里,我试图获取enab_test表中存在的禁令数量,如果禁止使用dvr_ind =' Y'然后它被计为一个,如果有许多相同的禁令,那么它被总结。如果在dms中有与dvr_ind =' Y'相同的禁令。对于禁令,将计数减去enab_test - oms_test。如果我们在从enab_test - oms_test中减去时有任何负数,则计数为零。和反之(oms_test-enab_test)。
下面是我处理的查询。
select nvl(enab.ENAB_COUNT,0) as ENAB_COUNT,
case when nvl(enab.ENAB_COUNT,0) - nvl(oms.OMS_COUNT,0) > 0
then nvl(enab.ENAB_COUNT,0) - nvl(oms.OMS_COUNT,0)
else 0
end as IN_ENAB_NOT_OMS
from (
select ban, count(*) as OMS_COUNT from oms_test
where dvr_ind = 'Y'
group by ban order by ban
) oms
full outer join (
select ban, count(*) as ENAB_COUNT from enab_test
where dvr_ind = 'Y'
group by ban order by ban
) enab
on oms.BAN = enab.BAN
以下是查询的输出
ENAB_COUNT IN_ENAB_NOT_OMS
2 1
0 0
1 1
1 1
运行计划对于上述查询,原始数据为
Plan hash value: 2599843784
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6705K| 166M| | 10M (9)| 33:33:17 |
| 1 | VIEW | VW_FOJ_0 | 6705K| 166M| | 10M (9)| 33:33:17 |
|* 2 | HASH JOIN FULL OUTER| | 6705K| 255M| 204M| 10M (9)| 33:33:17 |
| 3 | VIEW | | 6703K| 127M| | 4767K (9)| 15:53:31 |
| 4 | SORT GROUP BY | | 6703K| 76M| 14G| 4767K (9)| 15:53:31 |
|* 5 | TABLE ACCESS FULL| OMS_TEST | 764M| 8749M| | 3335K (7)| 11:07:08 |
| 6 | VIEW | | 6705K| 127M| | 5278K (9)| 17:35:37 |
| 7 | SORT GROUP BY | | 6705K| 76M| 15G| 5278K (9)| 17:35:37 |
|* 8 | TABLE ACCESS FULL| ENAB_TEST | 805M| 9215M| | 3770K (7)| 12:34:05 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OMS"."BAN"="ENAB"."BAN")
5 - filter("DVR_IND"='Y')
8 - filter("DVR_IND"='Y')
我创建了上面的查询,可以在较小的数据上正常工作。如果我有很多记录,它会占用太多时间。有没有办法删除完整的外连接并优化查询或任何其他优化方法?