ITPub博客

首页 > 数据库 > Oracle > [20241004]为什么这么慢.txt

[20241004]为什么这么慢.txt

原创 Oracle 作者:lfree 时间:2024-10-09 20:26:21 0 删除 编辑

[20241004]为什么这么慢.txt

--//家里无聊,做的一些测试,一些现象我无法解析。

1.环境:
SCOTT@book01p> @ ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

2.建立测试环境:
--//GRANT EXECUTE ON SYS.DBMS_LOCK TO SCOTT;
CREATE OR REPLACE FUNCTION SCOTT.sleep (seconds IN NUMBER)
   RETURN NUMBER
AS
BEGIN
   sys.DBMS_LOCK.sleep (seconds);
   RETURN seconds;
END;
/

SCOTT@book01p> create table tx as select level a from dual connect by level<=3 ;
Table created.

SCOTT@book01p> create table ty as select level a from dual connect by level<=3 ;
Table created.
--//分析略。

3.测试:
SCOTT@book01p> set timing on
SCOTT@book01p> SELECT sleep(a)  val FROM tx;
       VAL
----------
         1
         2
         3
Elapsed: 00:00:06.03
--//3+2+1=6秒没有问题.

--//测试前大家先猜测看执行如下需要多少秒?12秒?15秒?
SCOTT@book01p> @ sl all
alter session set statistics_level = all;
Session altered.

with t1 as ( SELECT /*+ inline */ sleep(a) val FROM tx),t2 as ( SELECT /*+ inline */ sleep(a) val FROM ty)
select * from t1 ,t2 WHERE t1.val = t2.val;

with t1 as ( SELECT  sleep(a) val FROM tx),t2 as ( SELECT sleep(a) val FROM ty)  select * from t1 ,t2 WHERE t1.val = t2.val;

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:24.28
--//噢,猜测不到需要24秒。看看执行计划:

SCOTT@book01p> @ dpc '' projection ''

PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  641xs1dhjk53y, child number 0
-------------------------------------
with t1 as ( SELECT  sleep(a) val FROM tx),t2 as ( SELECT sleep(a) val
FROM ty)  select * from t1 ,t2 WHERE t1.val = t2.val
Plan hash value: 1879928712
------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |       |     6 (100)|          |      3 |00:00:12.10 |       5 |       |       |          |
|*  1 |  HASH JOIN         |      |      1 |      1 |     6 |     6   (0)| 00:00:01 |      3 |00:00:12.10 |       5 |  2078K|  2078K|  963K (0)|
|   2 |   TABLE ACCESS FULL| TX   |      1 |      3 |     9 |     3   (0)| 00:00:01 |      3 |00:00:00.01 |       2 |       |       |          |
|   3 |   TABLE ACCESS FULL| TY   |      1 |      3 |     9 |     3   (0)| 00:00:01 |      3 |00:00:00.01 |       3 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$18780C30
   2 - SEL$18780C30 / "TX"@"SEL$1"
   3 - SEL$18780C30 / "TY"@"SEL$2"

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("SLEEP"("A")="SLEEP"("A"))

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=1) "A"[NUMBER,22], "A"[NUMBER,22]
   2 - "A"[NUMBER,22]
   3 - "A"[NUMBER,22]
35 rows selected.
--//A-Time  显示也是12.10,而实际的执行需要24秒。
--//注意看一个细节id=2,id=3.结合Column Projection Information (identified by operation id):部分:
--//仅仅取字段A,而不是sleep(A),id=2,3的a-time很小。
--//真正做HASH JOIN的是id=1,在这里调用函数sleep。消耗6+6秒。
--//在id=0时,select输出,再次调用sleep函数,导致再需要6+6秒这样总共24秒。

--//做1个10046跟踪就很清楚了。
$ grep "lock time"  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3832.trc
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 1008297 duration=0 p2=0 p3=0 obj#=24401 tim=3977086831
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 2019544 duration=0 p2=0 p3=0 obj#=24401 tim=3979106823
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 3000002 duration=0 p2=0 p3=0 obj#=24401 tim=3982107136
--//第1次扫描表tx,形成hash table。需要6秒
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 1018749 duration=0 p2=0 p3=0 obj#=24401 tim=3983126232
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 999545 duration=0 p2=0 p3=0 obj#=24401 tim=3984126149
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 1003211 duration=0 p2=0 p3=0 obj#=24401 tim=3985129576
--//第2次扫描表ty,先取出a=1,每条记录都调用sleep 3次作为比较。
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 2006211 duration=0 p2=0 p3=0 obj#=24401 tim=3987135920
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 2000298 duration=0 p2=0 p3=0 obj#=24401 tim=3989136349
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 2002598 duration=0 p2=0 p3=0 obj#=24401 tim=3991139069
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 3012665 duration=0 p2=0 p3=0 obj#=24401 tim=3994153622
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 3006930 duration=0 p2=0 p3=0 obj#=24401 tim=3997160698
WAIT #140437728019360: nam='PL/SQL lock timer' ela= 3001133 duration=0 p2=0 p3=0 obj#=24401 tim=4000161986

--//一个很简单验证如果输出不包括val(执行函数部分),就可以减少执行时间。
SCOTT@book01p> with t1 as ( SELECT  sleep(a) val,a FROM tx),t2 as ( SELECT sleep(a) val,a FROM ty)  select t1.a,t2.a from t1 ,t2 WHERE t1.val = t2.val;
       VAL        VAL
---------- ----------
         3          3
         2          2
         1          1
Elapsed: 00:00:12.11

--//使用MATERIALIZE提示就可以减少函数调用。
with t1 as ( SELECT /*+ MATERIALIZE */ sleep(a) val FROM tx),t2 as ( SELECT /*+ MATERIALIZE */ sleep(a) val FROM ty)
select * from t1 ,t2 WHERE t1.val = t2.val;

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:12.04

SCOTT@book01p> @ dpc '' projection ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  2081zkrcxfn69, child number 0
-------------------------------------
with t1 as ( SELECT /*+ MATERIALIZE */ sleep(a) val FROM tx),t2 as (
SELECT /*+ MATERIALIZE */ sleep(a) val FROM ty) select * from t1 ,t2
WHERE t1.val = t2.val
Plan hash value: 2067585427
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                | Name                      | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |                           |      1 |        |       |    10 (100)|          |      3 |00:00:12.04 |       6 |       |       |          |
|   1 |  TEMP TABLE TRANSFORMATION               |                           |      1 |        |       |            |          |      3 |00:00:12.04 |       6 |       |       |          |
|   2 |   LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_0FD9D6615_63B4FD |      1 |        |       |            |          |      0 |00:00:06.03 |       3 |  1024 |  1024 |          |
|   3 |    TABLE ACCESS FULL                     | TX                        |      1 |      3 |     9 |     3   (0)| 00:00:01 |      3 |00:00:00.01 |       2 |       |       |          |
|   4 |   LOAD AS SELECT (CURSOR DURATION MEMORY)| SYS_TEMP_0FD9D6616_63B4FD |      1 |        |       |            |          |      0 |00:00:06.01 |       2 |  1024 |  1024 |          |
|   5 |    TABLE ACCESS FULL                     | TY                        |      1 |      3 |     9 |     3   (0)| 00:00:01 |      3 |00:00:00.01 |       2 |       |       |          |
|*  6 |   HASH JOIN                              |                           |      1 |      1 |    26 |     4   (0)| 00:00:01 |      3 |00:00:00.01 |       0 |  2546K|  2546K| 1063K (0)|
|   7 |    VIEW                                  |                           |      1 |      3 |    39 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |       0 |       |       |          |
|   8 |     TABLE ACCESS FULL                    | SYS_TEMP_0FD9D6615_63B4FD |      1 |      3 |     9 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |       0 |       |       |          |
|   9 |    VIEW                                  |                           |      1 |      3 |    39 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |       0 |       |       |          |
|  10 |     TABLE ACCESS FULL                    | SYS_TEMP_0FD9D6616_63B4FD |      1 |      3 |     9 |     2   (0)| 00:00:01 |      3 |00:00:00.01 |       0 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$3
   2 - SEL$1
   3 - SEL$1        / "TX"@"SEL$1"
   4 - SEL$2
   5 - SEL$2        / "TY"@"SEL$2"
   7 - SEL$D67CB2D2 / "T1"@"SEL$3"
   8 - SEL$D67CB2D2 / "T1"@"SEL$D67CB2D2"
   9 - SEL$EC770CBA / "T2"@"SEL$3"
  10 - SEL$EC770CBA / "T1"@"SEL$EC770CBA"
Predicate Information (identified by operation id):
---------------------------------------------------
   6 - access("T1"."VAL"="T2"."VAL")
Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "T1"."VAL"[NUMBER,22], "T2"."VAL"[NUMBER,22]
   2 - SYSDEF[4], SYSDEF[0], SYSDEF[1], SYSDEF[120], SYSDEF[0]
   3 - "A"[NUMBER,22]
   4 - SYSDEF[4], SYSDEF[0], SYSDEF[1], SYSDEF[120], SYSDEF[0]
   5 - "A"[NUMBER,22]
   6 - (#keys=1) "T1"."VAL"[NUMBER,22], "T2"."VAL"[NUMBER,22]
   7 - (rowset=256) "T1"."VAL"[NUMBER,22]
   8 - (rowset=256) "C0"[NUMBER,22]
   9 - "T2"."VAL"[NUMBER,22]
  10 - "C0"[NUMBER,22]
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 2
---------------------------------------------------------------------------
   2 -  SEL$1
           -  MATERIALIZE
   4 -  SEL$2
           -  MATERIALIZE
66 rows selected.

--//如果写成如下呢?注意sleep(rownum)。
SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,
              ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t2
WHERE t1.val = t2.val;

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:13.11
--//为什么这样写,执行需要13秒呢?

SCOTT@book01p> @ dpc '' projection ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  ddyh0dg3w38a5, child number 0
-------------------------------------
SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <=
3) t1,               ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY
LEVEL <= 3) t2 WHERE t1.val = t2.val

Plan hash value: 155859586
---------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |      |      1 |        |       |     4 (100)|          |      3 |00:00:12.10 |       |       |          |
|*  1 |  HASH JOIN                      |      |      1 |      1 |    26 |     4   (0)| 00:00:01 |      3 |00:00:12.10 |  2546K|  2546K|  966K (0)|
|   2 |   VIEW                          |      |      1 |      1 |    13 |     2   (0)| 00:00:01 |      3 |00:00:06.08 |       |       |          |
|   3 |    COUNT                        |      |      1 |        |       |            |          |      3 |00:00:00.01 |       |       |          |
|   4 |     CONNECT BY WITHOUT FILTERING|      |      1 |        |       |            |          |      3 |00:00:00.01 |  2048 |  2048 | 2048  (0)|
|   5 |      FAST DUAL                  |      |      1 |      1 |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       |       |          |
|   6 |   VIEW                          |      |      1 |      1 |    13 |     2   (0)| 00:00:01 |      3 |00:00:06.02 |       |       |          |
|   7 |    COUNT                        |      |      1 |        |       |            |          |      3 |00:00:00.01 |       |       |          |
|   8 |     CONNECT BY WITHOUT FILTERING|      |      1 |        |       |            |          |      3 |00:00:00.01 |  2048 |  2048 | 2048  (0)|
|   9 |      FAST DUAL                  |      |      1 |      1 |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$2 / "T1"@"SEL$1"
   3 - SEL$2
   5 - SEL$2 / "DUAL"@"SEL$2"
   6 - SEL$3 / "T2"@"SEL$1"
   7 - SEL$3
   9 - SEL$3 / "DUAL"@"SEL$3"
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T1"."VAL"="T2"."VAL")
Column Projection Information (identified by operation id):
-----------------------------------------------------------
   1 - (#keys=1) "T1"."VAL"[NUMBER,22], "T2"."VAL"[NUMBER,22]
   2 - "T1"."VAL"[NUMBER,22]
   3 - ROWNUM[8]
   4 - LEVEL[4]
   6 - "T2"."VAL"[NUMBER,22]
   7 - ROWNUM[8]
   8 - LEVEL[4]
50 rows selected.

--//仔细看执行计划显示形成view,然后做hash join。按照道理怎么会多1秒呢?
--//如果在toad下执行就会发现显示的是12秒,为什么呢?这与sqlplus的fetch有关,缺省ROWPREFETCH=1,
--//一般fetch的数量是1,arraysize,arraysize,...剩下部分小于arraysize。
--//这个参数仅仅12c以上的sqlplus版本可以修改。

SCOTT@book01p> set rowprefetch 2
SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,
              ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t2
  WHERE t1.val = t2.val;

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:14.13

SCOTT@book01p> set rowprefetch 3
SCOTT@book01p> /

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:15.09
SCOTT@book01p> set rowprefetch 4
SCOTT@book01p> /

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:12.06

--//画一个表格:
rowprefetch  执行时间
----------------------
          1  13
          2  14
          3  15
          4  12
----------------------          

--//set rowprefetch 2 做一个10046跟踪,结果如下:
$ grep "lock time"  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3832_0001.trc
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 1003922 duration=0 p2=0 p3=0 obj#=24401 tim=4599768595
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2005582 duration=0 p2=0 p3=0 obj#=24401 tim=4601774372
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 3005814 duration=0 p2=0 p3=0 obj#=24401 tim=4604780368
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 1013875 duration=0 p2=0 p3=0 obj#=24401 tim=4605794487
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2100977 duration=0 p2=0 p3=0 obj#=24401 tim=4607895631
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2006217 duration=0 p2=0 p3=0 obj#=24401 tim=4609902047
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 3019542 duration=0 p2=0 p3=0 obj#=24401 tim=4612923536

--//跟踪内容如下:
*** 2024-10-04T16:25:21.864147+08:00 (BOOK01P(3))
WAIT #140437728019360: nam='SQL*Net message from client' ela= 1098883 driver id=1413697536 #bytes=1 p3=0 obj#=24401 tim=4598763528
CLOSE #140437728019360:c=9,e=9,dep=0,type=1,tim=4598763661
=====================
PARSING IN CURSOR #140437727524480 len=178 dep=0 uid=109 oct=3 lid=109 tim=4598763876 hv=109321450 ad='702ce860' sqlid='0u8agsn38877a'
SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,
              ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t2
  WHERE t1.val = t2.val
END OF STMT
PARSE #140437727524480:c=165,e=164,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=155859586,tim=4598763874
EXEC #140437727524480:c=77,e=76,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=155859586,tim=4598764061
WAIT #140437727524480: nam='SQL*Net message to client' ela= 3 driver id=1413697536 #bytes=1 p3=0 obj#=24401 tim=4598764141

*** 2024-10-04T16:25:22.869210+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 1003922 duration=0 p2=0 p3=0 obj#=24401 tim=4599768595

*** 2024-10-04T16:25:24.875003+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2005582 duration=0 p2=0 p3=0 obj#=24401 tim=4601774372

*** 2024-10-04T16:25:27.880989+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 3005814 duration=0 p2=0 p3=0 obj#=24401 tim=4604780368

*** 2024-10-04T16:25:28.895107+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 1013875 duration=0 p2=0 p3=0 obj#=24401 tim=4605794487

*** 2024-10-04T16:25:30.996254+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2100977 duration=0 p2=0 p3=0 obj#=24401 tim=4607895631
FETCH #140437727524480:c=1653,e=9131571,p=0,cr=0,cu=0,mis=0,r=2,dep=0,og=1,plh=155859586,tim=4607895763
--//r=2.

*** 2024-10-04T16:25:33.002666+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 2006217 duration=0 p2=0 p3=0 obj#=24401 tim=4609902047
WAIT #140437727524480: nam='SQL*Net message from client' ela= 1585 driver id=1413697536 #bytes=1 p3=0 obj#=24401 tim=4609903841
--//无法解析为什么重新执行sleep(2).视乎总是fetch的数量到达arraysize时重新读取最后1条。

*** 2024-10-04T16:25:36.024159+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='PL/SQL lock timer' ela= 3019542 duration=0 p2=0 p3=0 obj#=24401 tim=4612923536
WAIT #140437727524480: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=24401 tim=4612923661
FETCH #140437727524480:c=435,e=3019843,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,plh=155859586,tim=4612923753
--//r=1.
STAT #140437727524480 id=1 cnt=3 pid=0 pos=1 obj=0 op='HASH JOIN  (cr=0 pr=0 pw=0 str=1 time=12151372 us cost=4 size=26 card=1)'
STAT #140437727524480 id=2 cnt=3 pid=1 pos=1 obj=0 op='VIEW  (cr=0 pr=0 pw=0 str=1 time=6015966 us cost=2 size=13 card=1)'
STAT #140437727524480 id=3 cnt=3 pid=2 pos=1 obj=0 op='COUNT  (cr=0 pr=0 pw=0 str=1 time=67 us)'
STAT #140437727524480 id=4 cnt=3 pid=3 pos=1 obj=0 op='CONNECT BY WITHOUT FILTERING (cr=0 pr=0 pw=0 str=1 time=60 us)'
STAT #140437727524480 id=5 cnt=1 pid=4 pos=1 obj=0 op='FAST DUAL  (cr=0 pr=0 pw=0 str=1 time=2 us cost=2 size=0 card=1)'
STAT #140437727524480 id=6 cnt=3 pid=1 pos=2 obj=0 op='VIEW  (cr=0 pr=0 pw=0 str=1 time=6134942 us cost=2 size=13 card=1)'
STAT #140437727524480 id=7 cnt=3 pid=6 pos=1 obj=0 op='COUNT  (cr=0 pr=0 pw=0 str=1 time=54 us)'
STAT #140437727524480 id=8 cnt=3 pid=7 pos=1 obj=0 op='CONNECT BY WITHOUT FILTERING (cr=0 pr=0 pw=0 str=1 time=46 us)'
STAT #140437727524480 id=9 cnt=1 pid=8 pos=1 obj=0 op='FAST DUAL  (cr=0 pr=0 pw=0 str=1 time=1 us cost=2 size=0 card=1)'

*** 2024-10-04T16:25:41.639727+08:00 (BOOK01P(3))
WAIT #140437727524480: nam='SQL*Net message from client' ela= 5614581 driver id=1413697536 #bytes=1 p3=0 obj#=24401 tim=4618539112
CLOSE #140437727524480:c=46,e=45,dep=0,type=0,tim=4618539290
PARSE #140437730665600:c=8,e=9,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=0,tim=4618539361
EXEC #140437730665600:c=381,e=381,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=0,tim=4618539770


SCOTT@book01p> set arraysize 2
SCOTT@book01p> set rowprefetch 1

SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,
              ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t2
WHERE t1.val = t2.val;


       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3

Elapsed: 00:00:16.07

$ grep "lock time"  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3832_0002.trc
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 1007989 duration=0 p2=0 p3=0 obj#=-1 tim=5365884132
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 2007088 duration=0 p2=0 p3=0 obj#=-1 tim=5367891438
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 3004928 duration=0 p2=0 p3=0 obj#=-1 tim=5370896531
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 1028788 duration=0 p2=0 p3=0 obj#=-1 tim=5371925572
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 1001489 duration=0 p2=0 p3=0 obj#=-1 tim=5372927420
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 2000780 duration=0 p2=0 p3=0 obj#=-1 tim=5374930090
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 3007603 duration=0 p2=0 p3=0 obj#=-1 tim=5377937946
WAIT #140437725180264: nam='PL/SQL lock timer' ela= 3002644 duration=0 p2=0 p3=0 obj#=-1 tim=5380940882

SCOTT@book01p> set arraysize 2
SCOTT@book01p> set rowprefetch 1

SELECT * FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 6) t1,
              ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 6) t2
WHERE t1.val = t2.val;
       VAL        VAL
---------- ----------
         1          1
         2          2  --//停一下
         3          3
         4          4  --//停一下
         5          5
         6          6
6 rows selected.
Elapsed: 00:00:51.51

$ grep "lock time"  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3832_0003.trc
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 1003361 duration=0 p2=0 p3=0 obj#=-1 tim=5751379853
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 2004139 duration=0 p2=0 p3=0 obj#=-1 tim=5753384201
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 3012769 duration=0 p2=0 p3=0 obj#=-1 tim=5756397136
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 4003654 duration=0 p2=0 p3=0 obj#=-1 tim=5760400923
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 5011354 duration=0 p2=0 p3=0 obj#=-1 tim=5765412478
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 6012046 duration=0 p2=0 p3=0 obj#=-1 tim=5771424705

WAIT #140437729984976: nam='PL/SQL lock timer' ela= 1025651 duration=0 p2=0 p3=0 obj#=-1 tim=5772450679
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 1006917 duration=0 p2=0 p3=0 obj#=-1 tim=5773458196
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 2006345 duration=0 p2=0 p3=0 obj#=-1 tim=5775466558
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 3002809 duration=0 p2=0 p3=0 obj#=-1 tim=5778469546
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 3002833 duration=0 p2=0 p3=0 obj#=-1 tim=5781472619
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 4011207 duration=0 p2=0 p3=0 obj#=-1 tim=5785484372
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 5000575 duration=0 p2=0 p3=0 obj#=-1 tim=5790485205
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 5372975 duration=0 p2=0 p3=0 obj#=-1 tim=5795858417
WAIT #140437729984976: nam='PL/SQL lock timer' ela= 6012395 duration=0 p2=0 p3=0 obj#=-1 tim=5801871454
--//那位能给出更好的解析。
--//我测试许多例子,只要第2个表含有sleep(ROWNUM)就会出现这样的情况。
--//补充1个例子:
SELECT
/*+
LEADING(@"SEL$8976F1A6" "TX"@"SEL$3" "T1"@"SEL$1" )
USE_HASH(@"SEL$8976F1A6" "T1"@"SEL$1" ) */
* FROM ( SELECT sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,
              ( SELECT sleep(a) val FROM tx) t2
  WHERE t1.val = t2.val;

       VAL        VAL
---------- ----------
         1          1
         2          2
         3          3
Elapsed: 00:00:19.17
 
SCOTT@book01p> @ dpc '' projection,outline ''

PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  03nruuwk92tnk, child number 0
-------------------------------------
SELECT /*+ LEADING(@"SEL$8976F1A6" "TX"@"SEL$3" "T1"@"SEL$1" )
USE_HASH(@"SEL$8976F1A6" "T1"@"SEL$1" ) */ * FROM ( SELECT
sleep(ROWNUM) val FROM dual CONNECT BY LEVEL <= 3) t1,               (
SELECT sleep(a) val FROM tx) t2   WHERE t1.val = t2.val
Plan hash value: 4252884107
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |      |      1 |        |       |     5 (100)|          |      3 |00:00:12.05 |       3 |       |       |          |
|*  1 |  HASH JOIN                      |      |      1 |      1 |    16 |     5   (0)| 00:00:01 |      3 |00:00:12.05 |       3 |  2078K|  2078K|  945K (0)|
|   2 |   TABLE ACCESS FULL             | TX   |      1 |      3 |     9 |     3   (0)| 00:00:01 |      3 |00:00:00.01 |       3 |       |       |          |
|   3 |   VIEW                          |      |      1 |      1 |    13 |     2   (0)| 00:00:01 |      3 |00:00:06.02 |       0 |       |       |          |
|   4 |    COUNT                        |      |      1 |        |       |            |          |      3 |00:00:00.01 |       0 |       |       |          |
|   5 |     CONNECT BY WITHOUT FILTERING|      |      1 |        |       |            |          |      3 |00:00:00.01 |       0 |  2048 |  2048 | 2048  (0)|
|   6 |      FAST DUAL                  |      |      1 |      1 |       |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       0 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$8976F1A6
   2 - SEL$8976F1A6 / "TX"@"SEL$3"
   3 - SEL$2        / "T1"@"SEL$1"
   4 - SEL$2
   6 - SEL$2        / "DUAL"@"SEL$2"

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('21.1.0')
      DB_VERSION('21.1.0')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$8976F1A6")
      MERGE(@"SEL$3" >"SEL$1")
      OUTLINE(@"SEL$1")
      OUTLINE(@"SEL$3")
      FULL(@"SEL$8976F1A6" "TX"@"SEL$3")
      NO_ACCESS(@"SEL$8976F1A6" "T1"@"SEL$1")
      LEADING(@"SEL$8976F1A6" "TX"@"SEL$3" "T1"@"SEL$1")
      USE_HASH(@"SEL$8976F1A6" "T1"@"SEL$1")
      NO_CONNECT_BY_FILTERING(@"SEL$2")
      CONNECT_BY_COMBINE_SW(@"SEL$2")
      END_OUTLINE_DATA
  */

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."VAL"="SLEEP"("A"))

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - (#keys=1) "T1"."VAL"[NUMBER,22], "A"[NUMBER,22]
   2 - "A"[NUMBER,22]
   3 - "T1"."VAL"[NUMBER,22]
   4 - ROWNUM[8]
   5 - LEVEL[4]

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 2
---------------------------------------------------------------------------
   1 -  SEL$8976F1A6
           -  LEADING(@"SEL$8976F1A6" "TX"@"SEL$3" "T1"@"SEL$1" )

   1 -  SEL$8976F1A6 / "T1"@"SEL$1"
           -  USE_HASH(@"SEL$8976F1A6" "T1"@"SEL$1" )
77 rows selected.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3035704/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969783