Oracle 11g 递归+ exists运行计划的改变
有一个递归查询在10g上执行非常快,但在11g上执行不出来。
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
SQL> set timing on
SQL> set autotrace trace exp;--因为SQL运行出来须要两小时,所以就不运行了
SQL> SELECT *
FROM (SELECT DISTINCT A.*
FROM GG_MATERIAL_CLASSIFY A
CONNECT BY PRIOR PARENT_CLASSIFY_ID = CLASSIFY_ID
START WITH exists
(SELECT DISTINCT M.CLASSIFY_ID
FROM GG_DISTRIBUTION D, GG_MATERIAL M
WHERE D.MATERIAL_ID = M.MATERIAL_ID
AND A.CLASSIFY_ID=M.CLASSIFY_ID
AND D.ACTUAL_QTY > 0
AND D.DATA_AREA LIKE '03%')) B
WHERE B.PARENT_CLASSIFY_ID = '201'
ORDER BY B.CODE ASC;
运行计划
----------------------------------------------------------
Plan hash value: 3402505179
----------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------------------------------
| 0 | CREATE TABLE STATEMENT | | 68 | 27608 | 2433 (2)| 00:00:30 | | |
| 0 | SELECT STATEMENT | | 2 | 2174 | 15 (7)| 00:00:01 | | |
| 1 | LOAD AS SELECT | A0K_GG_MATERIAL_PAYMENT_140122 | | | | | | |
| 1 | SORT ORDER BY | | 2 | 2174 | 15 (7)| 00:00:01 | | |
|* 2 | TABLE ACCESS FULL | GG_MATERIAL_PAYMENT | 68 | 27608 | 2431 (2)| 00:00:30 | | |
|* 2 | VIEW | | 2 | 2174 | 15 (7)| 00:00:01 | | |
| 3 | HASH UNIQUE | | 2 | 412 | 15 (7)| 00:00:01 | | |
|* 4 | CONNECT BY NO FILTERING WITH SW (UNIQUE)| | | | | | | |
| 5 | TABLE ACCESS FULL | GG_MATERIAL_CLASSIFY | 1864 | 262K| 14 (0)| 00:00:01 | | |
|* 6 | HASH JOIN | | 1 | 65 | 207 (0)| 00:00:03 | | |
| 7 | TABLE ACCESS BY INDEX ROWID | GG_MATERIAL | 72 | 1512 | 24 (0)| 00:00:01 | | |
|* 8 | INDEX RANGE SCAN | RELATIONSHIP_84_FK | 72 | | 3 (0)| 00:00:01 | | |
|* 9 | TABLE ACCESS BY GLOBAL INDEX ROWID | GG_DISTRIBUTION | 1624 | 35728 | 183 (0)| 00:00:03 | ROWID | ROWID |
|* 10 | INDEX RANGE SCAN | IX_DISTRIBU_ACT_QTY01 | 144K| | 6 (0)| 00:00:01 | | |
----------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("GG_MATERIAL_PAYMENT"."PAYMENT_AMOUNT" IS NULL)
2 - filter("B"."PARENT_CLASSIFY_ID"='201')
4 - access("CLASSIFY_ID"=PRIOR "PARENT_CLASSIFY_ID")
filter( EXISTS (SELECT 0 FROM "GG_MATERIAL" "M","GG_DISTRIBUTION" "D" WHERE "D"."ACTUAL_QTY">0 AND "D"."DATA_AREA" LIKE '03%'
AND "M"."CLASSIFY_ID"=:B1 AND "D"."MATERIAL_ID"="M"."MATERIAL_ID"))
6 - access("D"."MATERIAL_ID"="M"."MATERIAL_ID")
8 - access("M"."CLASSIFY_ID"=:B1)
9 - filter("D"."DATA_AREA" LIKE '03%')
10 - access("D"."ACTUAL_QTY">0)
--网络上提供的方法1:改动隐含參数
SQL> alter session set "_optimizer_connect_by_elim_dups" = false;
SQL> alter session set "_connect_by_use_union_all" = "old_plan_mode";
SQL> SELECT *
2 FROM (SELECT DISTINCT A.*
3 FROM GG_MATERIAL_CLASSIFY A
4 CONNECT BY PRIOR PARENT_CLASSIFY_ID = CLASSIFY_ID
5 START WITH exists
6 (SELECT DISTINCT M.CLASSIFY_ID
7 FROM GG_DISTRIBUTION D, GG_MATERIAL M
8 WHERE D.MATERIAL_ID = M.MATERIAL_ID
9 AND A.CLASSIFY_ID=M.CLASSIFY_ID
10 AND D.ACTUAL_QTY > 0
11 AND D.DATA_AREA LIKE '03%')) B
12 WHERE B.PARENT_CLASSIFY_ID = '201'
13 ORDER BY B.CODE ASC;
已选择11行。
已用时间: 00: 00: 04.39
运行计划
----------------------------------------------------------
Plan hash value: 3792201725
----------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1087 | | 3 (34)| 00:00:01 | | |
| 1 | SORT ORDER BY | | 1 | 1087 | | 3 (34)| 00:00:01 | | |
|* 2 | VIEW | | 1 | 1087 | | 3 (34)| 00:00:01 | | |
| 3 | HASH UNIQUE | | 1 | 144 | | 3 (34)| 00:00:01 | | |
|* 4 | CONNECT BY WITH FILTERING | | | | | | | | |
| 5 | TABLE ACCESS BY INDEX ROWID | GG_MATERIAL_CLASSIFY | | | | | | | |
|* 6 | HASH JOIN | | 114K| 5816K| | 16615 (1)| 00:03:20 | | |
| 7 | INDEX FAST FULL SCAN | PK_GG_MATERIAL_CLASSIFY | 1864 | 16776 | | 3 (0)| 00:00:01 | | |
|* 8 | HASH JOIN | | 144K| 6051K| 3784K| 16610 (1)| 00:03:20 | | |
| 9 | INDEX FAST FULL SCAN | INX_GG_MATERIAL_CLASSIFY | 117K| 2403K| | 145 (2)| 00:00:02 | | |
|* 10 | TABLE ACCESS BY GLOBAL INDEX ROWID| GG_DISTRIBUTION | 144K| 3097K| | 16045 (1)| 00:03:13 | ROWID | ROWID |
|* 11 | INDEX RANGE SCAN | IX_DISTRIBU_ACT_QTY01 | 144K| | | 346 (1)| 00:00:05 | | |
| 12 | NESTED LOOPS | | | | | | | | |
| 13 | CONNECT BY PUMP | | | | | | | | |
| 14 | TABLE ACCESS BY INDEX ROWID | GG_MATERIAL_CLASSIFY | 1 | 144 | | 2 (0)| 00:00:01 | | |
|* 15 | INDEX UNIQUE SCAN | PK_GG_MATERIAL_CLASSIFY | 1 | | | 1 (0)| 00:00:01 | | |
----------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("B"."PARENT_CLASSIFY_ID"='201')
4 - access("CLASSIFY_ID"=PRIOR "PARENT_CLASSIFY_ID")
6 - access("A"."CLASSIFY_ID"="M"."CLASSIFY_ID")
8 - access("D"."MATERIAL_ID"="M"."MATERIAL_ID")
10 - filter("D"."DATA_AREA" LIKE '03%')
11 - access("D"."ACTUAL_QTY">0)
15 - access("CLASSIFY_ID"=PRIOR "PARENT_CLASSIFY_ID")
--网络上提供的方法2:失效。运行不出来(注意。要换一个session运行)
SELECT *
FROM (SELECT /*+ connect_by_filtering */DISTINCT A.*
FROM GG_MATERIAL_CLASSIFY A
CONNECT BY PRIOR PARENT_CLASSIFY_ID = CLASSIFY_ID
START WITH exists
(SELECT DISTINCT M.CLASSIFY_ID
FROM GG_DISTRIBUTION D, GG_MATERIAL M
WHERE D.MATERIAL_ID = M.MATERIAL_ID
AND A.CLASSIFY_ID=M.CLASSIFY_ID
AND D.ACTUAL_QTY > 0
AND D.DATA_AREA LIKE '03%')) B
WHERE B.PARENT_CLASSIFY_ID = '201'
ORDER BY B.CODE ASC;
对网络的方法总结,最好不要改动隐含參数,最多加上Hint,但Hint失效,所以再去找其它的方法。
无意之中把exits改为了in。问题攻克了。
SQL> set autotrace traceonly
SQL> SELECT *
FROM (SELECT DISTINCT A.*
FROM GG_MATERIAL_CLASSIFY A
CONNECT BY PRIOR PARENT_CLASSIFY_ID = CLASSIFY_ID
START WITH CLASSIFY_ID IN
(SELECT DISTINCT M.CLASSIFY_ID
FROM GG_DISTRIBUTION D, GG_MATERIAL M
WHERE D.MATERIAL_ID = M.MATERIAL_ID
AND D.ACTUAL_QTY > 0
AND D.DATA_AREA LIKE '03%')) B
WHERE B.PARENT_CLASSIFY_ID = '201'
ORDER BY B.CODE ASC;
已选择11行。
已用时间: 00: 00: 01.00
运行计划
----------------------------------------------------------
Plan hash value: 4133877384
------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | CREATE TABLE STATEMENT | | 645K| 57M| | 3895 (1)| 00:00:47 | | |
| 0 | SELECT STATEMENT | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
| 1 | LOAD AS SELECT | A2K_GG_INVOICE_ITEM_140106 | | | | | | | |
| 1 | SORT ORDER BY | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
| 2 | TABLE ACCESS FULL | GG_INVOICE_ITEM | 645K| 57M| | 1984 (2)| 00:00:24 | | |
|* 2 | VIEW | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
| 3 | HASH UNIQUE | | 3246 | 653K| | 16641 (1)| 00:03:20 | | |
|* 4 | CONNECT BY WITHOUT FILTERING (UNIQUE) | | | | | | | | |
|* 5 | HASH JOIN SEMI | | 1623 | 256K| | 16626 (1)| 00:03:20 | | |
| 6 | TABLE ACCESS FULL | GG_MATERIAL_CLASSIFY | 1864 | 262K| | 14 (0)| 00:00:01 | | |
| 7 | VIEW | VW_NSO_1 | 144K| 2533K| | 16610 (1)| 00:03:20 | | |
|* 8 | HASH JOIN | | 144K| 6051K| 3784K| 16610 (1)| 00:03:20 | | |
| 9 | INDEX FAST FULL SCAN | INX_GG_MATERIAL_CLASSIFY | 117K| 2403K| | 145 (2)| 00:00:02 | | |
|* 10 | TABLE ACCESS BY GLOBAL INDEX ROWID| GG_DISTRIBUTION | 144K| 3097K| | 16045 (1)| 00:03:13 | ROWID | ROWID |
|* 11 | INDEX RANGE SCAN | IX_DISTRIBU_ACT_QTY01 | 144K| | | 346 (1)| 00:00:05 | | |
| 12 | TABLE ACCESS FULL | GG_MATERIAL_CLASSIFY | 1864 | 262K| | 14 (0)| 00:00:01 | | |
------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("B"."PARENT_CLASSIFY_ID"='201')
4 - access("CLASSIFY_ID"=PRIOR "PARENT_CLASSIFY_ID")
5 - access("CLASSIFY_ID"="CLASSIFY_ID")
8 - access("D"."MATERIAL_ID"="M"."MATERIAL_ID")
10 - filter("D"."DATA_AREA" LIKE '03%')
11 - access("D"."ACTUAL_QTY">0)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
113928 consistent gets
0 physical reads
0 redo size
1960 bytes sent via SQL*Net to client
338 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
我看了一下in 和 exists产生运行计划的差别。从谓词从看到exists须要没有展开。所以我加了一个Hint验证了一下,运行结果跟in就是一样的了。
--unnest为展开子查询
SQL> SELECT *
FROM (SELECT DISTINCT A.*
FROM GG_MATERIAL_CLASSIFY A
CONNECT BY PRIOR PARENT_CLASSIFY_ID = CLASSIFY_ID
START WITH exists
(SELECT /*+unnest*/DISTINCT M.CLASSIFY_ID
FROM GG_DISTRIBUTION D, GG_MATERIAL M
WHERE D.MATERIAL_ID = M.MATERIAL_ID
AND A.CLASSIFY_ID=M.CLASSIFY_ID
AND D.ACTUAL_QTY > 0
AND D.DATA_AREA LIKE '03%')) B
WHERE B.PARENT_CLASSIFY_ID = '201'
ORDER BY B.CODE ASC;
已选择11行。
已用时间: 00: 00: 01.18
运行计划
----------------------------------------------------------
Plan hash value: 2653190462
----------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
| 1 | SORT ORDER BY | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
|* 2 | VIEW | | 3246 | 3445K| | 16641 (1)| 00:03:20 | | |
| 3 | HASH UNIQUE | | 3246 | 653K| | 16641 (1)| 00:03:20 | | |
|* 4 | CONNECT BY WITHOUT FILTERING (UNIQUE) | | | | | | | | |
|* 5 | HASH JOIN SEMI | | 1623 | 256K| | 16626 (1)| 00:03:20 | | |
| 6 | TABLE ACCESS FULL | GG_MATERIAL_CLASSIFY | 1864 | 262K| | 14 (0)| 00:00:01 | | |
| 7 | VIEW | VW_SQ_1 | 144K| 2533K| | 16610 (1)| 00:03:20 | | |
|* 8 | HASH JOIN | | 144K| 6051K| 3784K| 16610 (1)| 00:03:20 | | |
| 9 | INDEX FAST FULL SCAN | INX_GG_MATERIAL_CLASSIFY | 117K| 2403K| | 145 (2)| 00:00:02 | | |
|* 10 | TABLE ACCESS BY GLOBAL INDEX ROWID| GG_DISTRIBUTION | 144K| 3097K| | 16045 (1)| 00:03:13 | ROWID | ROWID |
|* 11 | INDEX RANGE SCAN | IX_DISTRIBU_ACT_QTY01 | 144K| | | 346 (1)| 00:00:05 | | |
| 12 | TABLE ACCESS FULL | GG_MATERIAL_CLASSIFY | 1864 | 262K| | 14 (0)| 00:00:01 | | |
----------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("B"."PARENT_CLASSIFY_ID"='201')
4 - access("CLASSIFY_ID"=PRIOR "PARENT_CLASSIFY_ID")
5 - access("A"."CLASSIFY_ID"="ITEM_0")
8 - access("D"."MATERIAL_ID"="M"."MATERIAL_ID")
10 - filter("D"."DATA_AREA" LIKE '03%')
11 - access("D"."ACTUAL_QTY">0)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
113928 consistent gets
0 physical reads
0 redo size
1960 bytes sent via SQL*Net to client
338 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
11 rows processed
Oracle 11g 递归+ exists运行计划的改变的更多相关文章
- 使用hint优化Oracle的运行计划 以及 SQL Tune Advisor的使用
背景: 某表忽然出现查询很缓慢的情况.cost 100+ 秒以上:严重影响生产. 原SQL: explain plan for select * from ( select ID id,RET_NO ...
- 【故障处理141119】一次数据库不繁忙时一条sql语句2个运行计划导致业务超时的故障处理
1,故障描写叙述: 一条select有两个运行计划.在sqlplus中运行选择好的运行计划.仅仅要40毫秒.而在程序中运行选择了差的运行计划,要1分23秒左右,导致前台业务超时报错. 2.故障解决: ...
- Oracle rownum影响运行计划
今天调优一条SQL语句,因为SQL比較复杂,用autotrace非常难一眼看出哪里出了问题,直接上10046. SELECT AB.* FROM (SELECT A.*, rownum RN FROM ...
- [Oracle] 获取运行计划的各方法总结
总的结论: 一.获取运行计划的6种方法(具体步骤已经在每一个样例的开头凝视部分说明了): 1. explain plan for获取: 2. set autotrace on . 3. stati ...
- Oracle 11g安装GI后,运行roothas.pl脚本报错libcap.so.1找不到
环境:RHEL6.4 + Oracle 11.2.0.3问题:需求是文件系统迁移到ASM,在安装GI后,运行roothas.pl脚本报错 1.运行root.sh后,按提示运行roothas.pl报错 ...
- Oracle 11g 执行计划管理1
1. 执行计划管理的工作原理 1.1控制执行计划的稳定性 11g之前,可以使用存储大纲(stored outline)和SQL Profile来固定某条SQL语句的执行计划,防止由于执行计划发生变化而 ...
- oracle分区表运行计划
分区表有非常多优点,以大化小,一小化了,加上并行的使用,在loap中能往往能提高几十倍甚至几百倍的效果. 当然表设计得不好也会适得其反.效果比普通表跟糟糕. 为了更好的使用分区表,这里看一下分区表的运 ...
- ORACLE 11G R2 RAC classical install OGG12.1(LINUX) 经典抽取模式单项同步配置OGG12.1
博文结构图如下: 一.环境描述以及注意事项 1.1 环境简介 IP 系统 Oracle版本 OGG版本 源端 172.16.10.16/36 RHEL6.5 oracle11204 12.1 目标端 ...
- 【转】oracle in和exists、not in和not exists原理和性能探究
转自http://www.2cto.com/database/201310/251176.html 对于in和exists.not in和not exists还是有很多的人有疑惑,更有甚者禁用not ...
随机推荐
- Objective-C类族和工厂模式
http://www.cocoachina.com/ios/20141124/10296.html 相信大家都了解GoF的<Design Patterns>中提到的23种设计模式,其中将常 ...
- 【linux高级程序设计】(第十三章)Linux Socket网络编程基础
IP地址定义: struct in_addr{ __u32 s_addr; }; in_addr_t inet_addr (__const char * __cp) :把点分十进制IP地址字符串转换 ...
- android 使用 LocalStorage
PS:本身是.net 出身 因为项目需要 研究了好几天安卓 这个方法网上也有 自己也写出来 有时间自己看看 和 给还没有解决问题的朋友借鉴下,下面有标个重点 是允许使用localstorage 的关键 ...
- javascript 仿面向对象编程实例代码(私有,公共变量。。。)
//定义一个javascript类 function JsClass(privateParam,publicParam){//构造函数 var priMember = privateParam; // ...
- 计蒜客 18492.Upside down primes-米勒拉宾判大素数 (German Collegiate Programming Contest 2015 ACM-ICPC Asia Training League 暑假第一阶段第三场 K)
K. Upside down primes 传送门 这个题就是把大数按字符串输进去,判断一下是不是素数,然后反转180度,先判断反转之后的东西是不是一个数,如果是的话,再把这个数判一下是不是素数,如果 ...
- Codeforces 832 B. Petya and Exam-字符串匹配
补的若干年以前的题目,水题,太菜啦_(:з」∠)_ B. Petya and Exam time limit per test 2 seconds memory limit per test ...
- CF987A Infinity Gauntlet【STL】
[链接]:CF987A [分析]:运用map [代码]: #include <iostream> #include<queue> #include<string.h> ...
- 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛)- 猴子排序的期望
链接:https://www.nowcoder.com/acm/contest/116/F来源:牛客网 题目描述 我们知道有一种神奇的排序方法叫做猴子排序,就是把待排序的数字写在卡片上,然后让猴子把卡 ...
- DTU
DTU 编辑 DTU (Data Transfer unit),是专门用于将串口数据转换为IP数据或将IP数据转换为串口数据通过无线通信网络进行传送的无线终端设备.DTU广泛应用于气象.水文水利.地质 ...
- Delphi CRC算法, 不错
http://www.cnblogs.com/tangqs/archive/2011/12/08/2280255.html