子查询内用nvl,到外层再关联怎么就像成笛卡尔积了
今天同事在公司写了个查询,就是在子查询里用了nvl,再到外城关联,成了笛卡尔
大概是这样的 create table object1 as
select distinct object_name nam
,1 as val
from all_objects
;create table object2 nologging as select * from object1;
create table table1 nologging as select * from object1;
create table table2 nologging as select * from object1;exec dbms_stats.gather_table_stats('scott','object1',cascade=>true);
exec dbms_stats.gather_table_stats('scott','object2',cascade=>true);
exec dbms_stats.gather_table_stats('scott','table1',cascade=>true);
exec dbms_stats.gather_table_stats('scott','table2',cascade=>true);explain plan for
select count(1)
from (select a.nam
,a.val+b.val val
from object1 a,table1 b
where a.nam=b.nam
)a
,(select a.nam
,a.val+b.val val
from object2 a,table2 b
where a.nam=b.nam
)b
where a.nam=b.nam
and a.val>=2
and b.val>=2
;
select * from table(dbms_xplan.display) ;PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 3856415621---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 110 | 115 (7)| 00:00:02 |
| 1 | SORT AGGREGATE | | 1 | 110 | | |
|* 2 | HASH JOIN | | 56 | 6160 | 115 (7)| 00:00:02 |
|* 3 | HASH JOIN | | 1126 | 92332 | 86 (6)| 00:00:02 |
|* 4 | HASH JOIN | | 1126 | 61930 | 57 (6)| 00:00:01 |
| 5 | TABLE ACCESS FULL| OBJECT2 | 22522 | 593K| 28 (4)| 00:00:01 |
| 6 | TABLE ACCESS FULL| TABLE2 | 22786 | 623K| 28 (4)| 00:00:01 |
| 7 | TABLE ACCESS FULL | OBJECT1 | 22771 | 600K| 28 (4)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TABLE1 | 22535 | 616K| 28 (4)| 00:00:01 |
---------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)
3 - access("A"."NAM"="A"."NAM")
4 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)explain plan for
select count(1)
from (select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object1 a,table1 b
where a.nam=b.nam
)a
,(select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object2 a,table2 b
where a.nam=b.nam
)b
where a.nam=b.nam
and a.val>=2
and b.val>=2
;
select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 3388926023----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 110 | 29501 (5)| 00:05:55 |
| 1 | SORT AGGREGATE | | 1 | 110 | | |
|* 2 | HASH JOIN | | 12688 | 1362K| 29501 (5)| 00:05:55 |
| 3 | TABLE ACCESS FULL | OBJECT1 | 22771 | 600K| 28 (4)| 00:00:01 |
| 4 | MERGE JOIN CARTESIAN| | 25M| 2008M| 29036 (4)| 00:05:49 |
|* 5 | HASH JOIN | | 1126 | 61930 | 57 (6)| 00:00:01 |
| 6 | TABLE ACCESS FULL | OBJECT2 | 22522 | 593K| 28 (4)| 00:00:01 |
| 7 | TABLE ACCESS FULL | TABLE2 | 22786 | 623K| 28 (4)| 00:00:01 |
| 8 | BUFFER SORT | | 22535 | 616K| 29009 (4)| 00:05:49 |
| 9 | TABLE ACCESS FULL | TABLE1 | 22535 | 616K| 26 (4)| 00:00:01 |
----------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."NAM"="B"."NAM")
filter(NVL("A"."NAM","B"."NAM")=NVL("A"."NAM","B"."NAM") AND
"A"."VAL"+"B"."VAL">=2)
5 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)2个脚本结果是一样的
第二个由于子查询用了nvl,其实可以不用的,只是复制其他脚本时本来用full join 的
以为不影响结果就没改了
到外层就成NVL("A"."NAM","B"."NAM")=NVL("A"."NAM","B"."NAM") 了,这不成了笛卡尔积了吗
今天同事在公司写了个查询,就是在子查询里用了nvl,再到外城关联,成了笛卡尔
大概是这样的 create table object1 as
select distinct object_name nam
,1 as val
from all_objects
;create table object2 nologging as select * from object1;
create table table1 nologging as select * from object1;
create table table2 nologging as select * from object1;exec dbms_stats.gather_table_stats('scott','object1',cascade=>true);
exec dbms_stats.gather_table_stats('scott','object2',cascade=>true);
exec dbms_stats.gather_table_stats('scott','table1',cascade=>true);
exec dbms_stats.gather_table_stats('scott','table2',cascade=>true);explain plan for
select count(1)
from (select a.nam
,a.val+b.val val
from object1 a,table1 b
where a.nam=b.nam
)a
,(select a.nam
,a.val+b.val val
from object2 a,table2 b
where a.nam=b.nam
)b
where a.nam=b.nam
and a.val>=2
and b.val>=2
;
select * from table(dbms_xplan.display) ;PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 3856415621---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 110 | 115 (7)| 00:00:02 |
| 1 | SORT AGGREGATE | | 1 | 110 | | |
|* 2 | HASH JOIN | | 56 | 6160 | 115 (7)| 00:00:02 |
|* 3 | HASH JOIN | | 1126 | 92332 | 86 (6)| 00:00:02 |
|* 4 | HASH JOIN | | 1126 | 61930 | 57 (6)| 00:00:01 |
| 5 | TABLE ACCESS FULL| OBJECT2 | 22522 | 593K| 28 (4)| 00:00:01 |
| 6 | TABLE ACCESS FULL| TABLE2 | 22786 | 623K| 28 (4)| 00:00:01 |
| 7 | TABLE ACCESS FULL | OBJECT1 | 22771 | 600K| 28 (4)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TABLE1 | 22535 | 616K| 28 (4)| 00:00:01 |
---------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)
3 - access("A"."NAM"="A"."NAM")
4 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)explain plan for
select count(1)
from (select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object1 a,table1 b
where a.nam=b.nam
)a
,(select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object2 a,table2 b
where a.nam=b.nam
)b
where a.nam=b.nam
and a.val>=2
and b.val>=2
;
select * from table(dbms_xplan.display) ;
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 3388926023----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 110 | 29501 (5)| 00:05:55 |
| 1 | SORT AGGREGATE | | 1 | 110 | | |
|* 2 | HASH JOIN | | 12688 | 1362K| 29501 (5)| 00:05:55 |
| 3 | TABLE ACCESS FULL | OBJECT1 | 22771 | 600K| 28 (4)| 00:00:01 |
| 4 | MERGE JOIN CARTESIAN| | 25M| 2008M| 29036 (4)| 00:05:49 |
|* 5 | HASH JOIN | | 1126 | 61930 | 57 (6)| 00:00:01 |
| 6 | TABLE ACCESS FULL | OBJECT2 | 22522 | 593K| 28 (4)| 00:00:01 |
| 7 | TABLE ACCESS FULL | TABLE2 | 22786 | 623K| 28 (4)| 00:00:01 |
| 8 | BUFFER SORT | | 22535 | 616K| 29009 (4)| 00:05:49 |
| 9 | TABLE ACCESS FULL | TABLE1 | 22535 | 616K| 26 (4)| 00:00:01 |
----------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."NAM"="B"."NAM")
filter(NVL("A"."NAM","B"."NAM")=NVL("A"."NAM","B"."NAM") AND
"A"."VAL"+"B"."VAL">=2)
5 - access("A"."NAM"="B"."NAM")
filter("A"."VAL"+"B"."VAL">=2)2个脚本结果是一样的
第二个由于子查询用了nvl,其实可以不用的,只是复制其他脚本时本来用full join 的
以为不影响结果就没改了
到外层就成NVL("A"."NAM","B"."NAM")=NVL("A"."NAM","B"."NAM") 了,这不成了笛卡尔积了吗
解决方案 »
- 查找并显示一个表的所有字段含义(不是字段名称) 很急,谢谢
- 求助oracle 11g的对于空表的问题!
- 发现在Users组权限下运行OraClient10g_home1(Windows32位版本)会报错,请求解决。
- 深圳ORACLE大型技术沙龙现场视频免费下载
- 入门求教:80分,解决就结贴!在苦里,创建了表空及其表,如何在java程序中访问?
- 这样创建数据库为什么会错的?
- 关于用户创建和授权的问题,急!!!在线给分
- 如何删去Oracle表中的重复记录??
- 为什么建不了表分区?
- Oracle 的 控制台中 怎么没有 Database 节点???
- oracle 中下面哪里出现的错误 怎么老是执行不了
- ORACLE FUNCTION问题,大惑不解请高手指点如何解决?
但效率却相差甚远
本来几秒的查询变成几分钟
在公司的实际数据,本来半个钟能出来的,7天都没出子查询改成full join ,倒正常了explain plan for
select count(1)
from (select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object1 a
full join table1 b
on a.nam=b.nam
)a
,(select nvl(a.nam,b.nam) nam
,a.val+b.val val
from object2 a
full join table2 b
on a.nam=b.nam
)b
where a.nam=b.nam
and a.val>=2
and b.val>=2
;
select * from table(dbms_xplan.display) ;PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 3244338705-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 68 | | 419 (25)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 68 | | | |
|* 2 | HASH JOIN | | 5201K| 337M| 1024K| 419 (25)| 00:00:06 |
| 3 | VIEW | | 22772 | 756K| | 114 (6)| 00:00:02 |
| 4 | UNION-ALL | | | | | | |
|* 5 | FILTER | | | | | | |
|* 6 | HASH JOIN OUTER | | 22771 | 1223K| | 57 (6)| 00:00:01 |
| 7 | TABLE ACCESS FULL| OBJECT1 | 22771 | 600K| | 28 (4)| 00:00:01 |
| 8 | TABLE ACCESS FULL| TABLE1 | 22535 | 616K| | 28 (4)| 00:00:01 |
|* 9 | HASH JOIN ANTI | | 1 | 53 | | 57 (6)| 00:00:01 |
|* 10 | TABLE ACCESS FULL | TABLE1 | 1127 | 31556 | | 28 (4)| 00:00:01 |
| 11 | TABLE ACCESS FULL | OBJECT1 | 22771 | 555K| | 28 (4)| 00:00:01 |
| 12 | VIEW | | 22843 | 758K| | 114 (6)| 00:00:02 |
| 13 | UNION-ALL | | | | | | |
|* 14 | FILTER | | | | | | |
|* 15 | HASH JOIN OUTER | | 22522 | 1209K| | 57 (6)| 00:00:01 |
| 16 | TABLE ACCESS FULL| OBJECT2 | 22522 | 593K| | 28 (4)| 00:00:01 |
| 17 | TABLE ACCESS FULL| TABLE2 | 22786 | 623K| | 28 (4)| 00:00:01 |
|* 18 | HASH JOIN ANTI | | 321 | 17013 | | 57 (6)| 00:00:01 |
|* 19 | TABLE ACCESS FULL | TABLE2 | 1139 | 31892 | | 28 (4)| 00:00:01 |
| 20 | TABLE ACCESS FULL | OBJECT2 | 22522 | 549K| | 28 (4)| 00:00:01 |
-------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access(NVL("A"."NAM","B"."NAM")=NVL("A"."NAM","B"."NAM"))
5 - filter("A"."VAL"+"B"."VAL">=2)
6 - access("A"."NAM"="B"."NAM"(+))
9 - access("A"."NAM"="B"."NAM")
10 - filter(TO_NUMBER(NULL)+"B"."VAL">=2)
14 - filter("A"."VAL"+"B"."VAL">=2)
15 - access("A"."NAM"="B"."NAM"(+))
18 - access("A"."NAM"="B"."NAM")
19 - filter(TO_NUMBER(NULL)+"B"."VAL">=2)
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 110 | 29501 (5)| 00:05:55 |
| 1 | SORT AGGREGATE | | 1 | 110 | | |
|* 2 | HASH JOIN | | 12688 | 1362K| 29501 (5)| 00:05:55 |
| 3 | TABLE ACCESS FULL | OBJECT1 | 22771 | 600K| 28 (4)| 00:00:01 |
| 4 | MERGE JOIN CARTESIAN| | 25M| 2008M| 29036 (4)| 00:05:49 |
|* 5 | HASH JOIN | | 1126 | 61930 | 57 (6)| 00:00:01 |
| 6 | TABLE ACCESS FULL | OBJECT2 | 22522 | 593K| 28 (4)| 00:00:01 |
| 7 | TABLE ACCESS FULL | TABLE2 | 22786 | 623K| 28 (4)| 00:00:01 |
| 8 | BUFFER SORT | | 22535 | 616K| 29009 (4)| 00:05:49 |
| 9 | TABLE ACCESS FULL | TABLE1 | 22535 | 616K| 26 (4)| 00:00:01 |
----------------------------------------------------------------------------------关键是上面的那一个排序操作,COST太高