如何獲取真實的執行計劃

pwz1688發表於2016-06-15

在ORACLE中,一條SQL的執行計劃可以幫助我們瞭解該SQL的執行步驟,從而判斷相應的執行計劃是否合理,其瓶頸在何處等。所以,執行計劃是我們調整SQL的一個重要參考。
在說明如何獲取真實的執行計劃前,我們先看一下通常獲取執行計劃的幾種方法:
1、explain for ... 
2、set autotrace on
3、 dbms_xplan.display_cursor
4、 10046 trace跟蹤
5、 awrsqrpt.sql

在進行具體的演示前,我們均以下面的SQL做為樣例。
 SELECT  *

FROM t1, t2

WHERE t1.id = t2.t1_id

AND t1.n in(18,19);

 

其中,t1表有記錄1000行,t2表有記錄100000行;在T1表的n列和T2表的T1_id列上建有索引。

 

  方法1:explain plan for

SQL> explain plan for

    SELECT  *

FROM t1, t2

WHERE t1.id = t2.t1_id

AND t1.n in(18,19);  

 

Explained.

 

SQL> select * from table(dbms_xplan.display());

Plan hash value: 128660979

 

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time          |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT          |   |   2 |  8138 |      8   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID   | T2          |   1 |  2041 |      2   (0)| 00:00:01 |

|   2 |   NESTED LOOPS                       |   |   2 |  8138 |      8   (0)| 00:00:01 |

|   3 |    INLIST ITERATOR        |   |     |     |          |   |

|   4 |     TABLE ACCESS BY INDEX ROWID| T1          |   2 |  4056 |      4   (0)| 00:00:01 |

|*  5 |      INDEX RANGE SCAN               | T1_N          |   4 |      |   2   (0)| 00:00:01 |

|*  6 |    INDEX RANGE SCAN           | T2_T1_ID |      1 |      |   1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   5 - access("T1"."N"=18 OR "T1"."N"=19)

   6 - access("T1"."ID"="T2"."T1_ID")

 

Note

-----

   - dynamic sampling used for this statement

 

23 rows selected.

特點:1、不會真正執行SQL語句。故,執行計劃結果返回快,無SQL語句的執行結果輸出,返回的執行計劃可能不是真正的執行計劃。

         2、無統計資訊

注:在一些圖形化開發和管理整合工具中(比如PL/SQL DEVELOPER)檢視執行計劃,其實質就是使用explain for的方法。

     

 

     方法2: set autotrace on;

SQL> set autotrace on

SQL> set pagesize 2000;

SQL> SELECT  *

FROM t1, t2

WHERE t1.id = t2.t1_id

AND t1.n in(18,19);  2    3    4 

 

         ID         N

---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         ID     T1_ID              N

---------- ---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         18        18

yFfYpcNtsxEpvWUOceJmHtvpCEbcJTUTeKExdHlGlwoIFEgmOo

         18        18             18

OWCPIKKFQTMBZAVJBUGPOGOZGPHCMTGFDJTMCIZXRFVXYCATTY

 

         19        19

jAOYAJHBzwhNWHImZeFUOaxvMycbQsCLKhsUnSFwZpyctEahjK

         19        19             19

BEQUUMJSUDRLTCGOCIUHSZCNNJOTZOCEQKBZPSLHGAKRTLJAHX

 

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 128660979

 

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time          |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT          |   |   2 |  4198 |      8   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID   | T2          |   1 |  2041 |      2   (0)| 00:00:01 |

|   2 |   NESTED LOOPS                       |   |   2 |  4198 |      8   (0)| 00:00:01 |

|   3 |    INLIST ITERATOR        |   |     |     |          |   |

|   4 |     TABLE ACCESS BY INDEX ROWID| T1          |   2 |   116 |      4   (0)| 00:00:01 |

|*  5 |      INDEX RANGE SCAN               | T1_N          |   2 |      |   2   (0)| 00:00:01 |

|*  6 |    INDEX RANGE SCAN           | T2_T1_ID |      1 |      |   1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   5 - access("T1"."N"=18 OR "T1"."N"=19)

   6 - access("T1"."ID"="T2"."T1_ID")

 

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

           0  recursive calls

           0  db block gets

          14  consistent gets

           0  physical reads

           0  redo size

       1164  bytes sent via SQL*Net to client

         492  bytes received via SQL*Net from client

           2  SQL*Net roundtrips to/from client

           0  sorts (memory)

           0  sorts (disk)

           2  rows processed

 

SQL>

 

特點:1SQL語句被執行。故,執行計劃結果的返回時間的快慢,取決於SQL語句執行時間的長短。有SQL語句執行結果的輸出。

         2、有統計資訊

 

     方法3:dbms_xplan.display_cursor
使用ORACLE資料庫內建的dbms_xplan包來獲取執行計劃,也是常用的方法之一。根據呼叫包中過程及引數的不同,可以衍生出很多種方法。這裡我們只介紹最常用的2種。
注意,我們這裡使用的是 dbms_xplan.display_cursor,而不是方法1中使用的dbms_xplan.display,雖然同屬一個包,但方法是不同的,不要搞混。

(1)、
設定會話選項為statistics_level=all後,用dbms_xplan.display_cursor(null,null,’allstats last’)檢視執行計劃。

SQL> alter session set statistics_level=all ;

SQL> SET AUTOTRACE OFF             --如果此前該開關為ON的狀態,會影響我們後續的執行計劃的獲取和輸出。所以,這裡的目的是確保該開關已關閉。                

SQL> SELECT  * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19);

 

         ID         N

---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         ID     T1_ID              N

---------- ---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         18        18

yFfYpcNtsxEpvWUOceJmHtvpCEbcJTUTeKExdHlGlwoIFEgmOo

         18        18             18

OWCPIKKFQTMBZAVJBUGPOGOZGPHCMTGFDJTMCIZXRFVXYCATTY

 

         19        19

jAOYAJHBzwhNWHImZeFUOaxvMycbQsCLKhsUnSFwZpyctEahjK

         19        19             19

BEQUUMJSUDRLTCGOCIUHSZCNNJOTZOCEQKBZPSLHGAKRTLJAHX

 

 

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

 

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------

SQL_ID     cshvm6ngravw0, child number 0

-------------------------------------

SELECT     * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19)

 

Plan hash value: 128660979

 

-----------------------------------------------------------------------------------------------------

| Id  | Operation                    | Name         | Starts | E-Rows | A-Rows |       A-Time   | Buffers |

-----------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT          |   |   0 |      |          0 |00:00:00.01 |           0 |

|   1 |  TABLE ACCESS BY INDEX ROWID   | T2          |   1 |    1 |            2 |00:00:00.01 |         14 |

|   2 |   NESTED LOOPS                       |   |   1 |    2 |            5 |00:00:00.01 |         12 |

|   3 |    INLIST ITERATOR        |   |   1 |      |          2 |00:00:00.01 |           7 |

|   4 |     TABLE ACCESS BY INDEX ROWID| T1          |   2 |    2 |            2 |00:00:00.01 |           7 |

|*  5 |      INDEX RANGE SCAN               | T1_N          |   2 |    2 |            2 |00:00:00.01 |           5 |

|*  6 |    INDEX RANGE SCAN           | T2_T1_ID |      2 |    1 |            2 |00:00:00.01 |           5 |

-----------------------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   5 - access(("T1"."N"=18 OR "T1"."N"=19))

   6 - access("T1"."ID"="T2"."T1_ID")

 

Note

-----

   - dynamic sampling used for this statement

 

 

28 rows selected.

 

特點:1SQL語句只有被執行過,才能得到其執行計劃。故,得到執行計劃時間的快慢,取決於SQL語句執行時間的長短。有SQL語句執行結果的輸出。

        2、可以看到表被訪問的次數(執行計劃中的STARTS列內容)。

        3、可以看到執行計劃各步驟中,實際得到的結果集行數(A-ROWS)與評估得到的結果集行數(E-ROWS)。利用該資訊,可以判斷統計資訊是否準確。

        4、可以看到各執行計劃步驟實際經歷的時間(A-TIME),利用該資訊,可以快速找到最耗時的執行計劃步驟。

        5、無統計資訊的輸出,但執行計劃中有邏輯讀次數的資訊(執行計劃中的BUFFERS列內容)。

 

     (2)、 dbms_xplan.display_cursor()輸入SQL_ID的方法
先通過以下SQL,獲取相應SQL的SQL_ID.
 注:使用這種方法,要求相應SQL的執行計劃還在記憶體中,即還沒有被排出SHARED POOL。否則,查詢結果會為空。

SQL>  SELECT sql_id,CHILD_NUMBER FROM v$sql A WHERE sql_text LIKE 'SELECT  * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19)%';

 

SQL_ID           CHILD_NUMBER

------------- ------------

cshvm6ngravw0                0

 

SQL> select * from table(dbms_xplan.display_cursor('cshvm6ngravw0'));

 

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------

SQL_ID     cshvm6ngravw0, child number 0

-------------------------------------

SELECT     * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19)

 

Plan hash value: 128660979

 

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time          |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT          |   |    |     |   8 (100)|      |

|   1 |  TABLE ACCESS BY INDEX ROWID   | T2          |   1 |  2041 |      2   (0)| 00:00:01 |

|   2 |   NESTED LOOPS                       |   |   2 |  4198 |      8   (0)| 00:00:01 |

|   3 |    INLIST ITERATOR        |   |     |     |          |   |

|   4 |     TABLE ACCESS BY INDEX ROWID| T1          |   2 |   116 |      4   (0)| 00:00:01 |

|*  5 |      INDEX RANGE SCAN               | T1_N          |   2 |      |   2   (0)| 00:00:01 |

|*  6 |    INDEX RANGE SCAN           | T2_T1_ID |      1 |      |   1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   5 - access(("T1"."N"=18 OR "T1"."N"=19))

   6 - access("T1"."ID"="T2"."T1_ID")

 

Note

-----

   - dynamic sampling used for this statement

 

 

28 rows selected.

 

特點:1SQL語句只有被執行過,才能得到其執行計劃。故,得到執行計劃時間的快慢,取決於SQL語句執行時間的長短。有SQL語句執行結果的輸出。

         2、無統計資訊


     方法4: 10046 trace跟蹤

SQL> alter session set events '10046 trace name context  forever,level 12';  --開啟跟蹤

 

Session altered.

 

SQL> SELECT  * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19);  --執行相應的SQL

 

         ID         N

---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         ID     T1_ID              N

---------- ---------- ----------

CONTENTS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

         18        18

yFfYpcNtsxEpvWUOceJmHtvpCEbcJTUTeKExdHlGlwoIFEgmOo

         18        18             18

OWCPIKKFQTMBZAVJBUGPOGOZGPHCMTGFDJTMCIZXRFVXYCATTY

 

         19        19

jAOYAJHBzwhNWHImZeFUOaxvMycbQsCLKhsUnSFwZpyctEahjK

         19        19             19

BEQUUMJSUDRLTCGOCIUHSZCNNJOTZOCEQKBZPSLHGAKRTLJAHX

 

 

SQL> alter session set events '10046 trace name context off';   --關閉跟蹤。

 

Session altered.

 
--通過以下SQL,獲取跟蹤期間產生的跟蹤檔案的所在位置。

SQL> select d.value

|| '/'

|| LOWER (RTRIM(i.INSTANCE, CHR(0)))

|| '_ora_'

|| p.spid

|| '.trc' trace_file_name

from (select p.spid

      from v$mystat m,v$session s, v$process p

      where  m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p,

  2    3    4    5    6    7    8    9   10        (select t.INSTANCE

       FROM v$thread t,v$parameter v

       WHERE v.name='thread'

       AND(v.VALUE=0 OR t.thread#=to_number(v.value))) i,

       (select value

       from v$parameter

       where name='user_dump_dest') d; 11   12   13   14   15   16 

 

TRACE_FILE_NAME

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

/oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc

 

SQL> exit

Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

--通過以下命令,進行跟蹤檔案的轉換,以方便閱讀。

[oracle@localhost ~]$ tkprof /oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc 10046.txt sys=no sort=prsela,exeela,fchela

 

TKPROF: Release 10.2.0.5.0 - Production on Sun Apr 27 11:06:18 2014

 

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

 

 

[oracle@localhost ~]$ ll

total 280

-rw-r--r-- 1 oracle oinstall   5537 Apr 27 11:06 10046.txt

-rw-r--r-- 1 oracle oinstall    797 Feb  9 12:14 demo.txt

-rw-r--r-- 1 oracle oinstall  30335 Nov 23 14:29 zyash.html

-rw-r--r-- 1 oracle oinstall 234760 Nov 23 14:04 zyawr.rpt

[oracle@localhost ~]$ cat 10046.txt

 

TKPROF: Release 10.2.0.5.0 - Production on Sun Apr 27 11:06:18 2014

 

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

 

Trace file: /oracle/app/oracle/admin/orcl/udump/orcl_ora_2509.trc

Sort options: prsela  exeela  fchela 

********************************************************************************

count    = number of times OCI procedure was executed

cpu      = cpu time in seconds executing

elapsed  = elapsed time in seconds executing

disk     = number of physical reads of buffers from disk

query    = number of buffers gotten for consistent read

current  = number of buffers gotten in current mode (usually for update)

rows     = number of rows processed by the fetch or execute call

********************************************************************************

 

SELECT  *

FROM

 t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18,19)

 

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      0.00       0.00          0         14          0           2

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        4      0.00       0.00          0         14          0           2

 

Misses in library cache during parse: 0

Optimizer mode: ALL_ROWS

Parsing user id: 54 

 

Rows     Row Source Operation

-------  ---------------------------------------------------

      2  TABLE ACCESS BY INDEX ROWID T2 (cr=14 pr=0 pw=0 time=142 us)

      5   NESTED LOOPS  (cr=12 pr=0 pw=0 time=79 us)

      2    INLIST ITERATOR  (cr=7 pr=0 pw=0 time=53 us)

      2     TABLE ACCESS BY INDEX ROWID T1 (cr=7 pr=0 pw=0 time=46 us)

      2      INDEX RANGE SCAN T1_N (cr=5 pr=0 pw=0 time=33 us)(object id 51619)

      2    INDEX RANGE SCAN T2_T1_ID (cr=5 pr=0 pw=0 time=25 us)(object id 51620)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                       2        0.00          0.00

  SQL*Net message from client                     2       30.60         30.60

 

特點:1SQL語句只有被執行過,才能得到其執行計劃。故,得到執行計劃時間的快慢,取決於SQL語句執行時間的長短。有SQL語句執行結果的輸出。

        2、獲取執行計劃的步驟較複雜。

        3、解析時間和執行時間分別列出

        4、可以看到相關的統計資訊(邏輯讀、物理讀、寫等,執行計劃中的每一步執行時間精確到微秒)

        5、如果SQL語句中有函式呼叫,SQL中有SQL,將會都被列出

        6、看不到謂詞資訊

 

    方法5: awrsqrpt.sql
該方法主要用於獲取已經被排出SHARED POOL,即,無法在v$sql中查詢出來,但仍在AWR快照中的歷史SQL。

SQL> @?/rdbms/admin/awrsqrpt.sql

 

Current Instance

~~~~~~~~~~~~~~~~

 

   DB Id    DB Name  Inst Num Instance

----------- ------------ -------- ------------

 1347935162 ORCL          1 orcl

 

 

Specify the Report Type

~~~~~~~~~~~~~~~~~~~~~~~

Would you like an HTML report, or a plain text report?

Enter 'html' for an HTML report, or 'text' for plain text

Defaults to 'html'

Enter value for report_type:

 

Type Specified:  html

 

 

Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

   DB Id     Inst Num DB Name            Instance     Host

------------ -------- ------------ ------------ ------------

* 1347935162     1 ORCL        orcl   localhost.lo

                                                        caldomain

 

Using 1347935162 for database Id

Using               1 for instance number

 

 

Specify the number of days of snapshots to choose from

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Entering the number of days (n) will result in the most recent

(n) days of snapshots being listed.  Pressing without

specifying a number lists all completed snapshots.

 

 

Enter value for num_days: 1

 

Listing the last day's Completed Snapshots

 

                                                                 Snap

Instance     DB Name     Snap Id    Snap Started    Level

------------ ------------ --------- ------------------ -----

orcl       ORCL               533 27 Apr 2014 09:59       1

                                     534 27 Apr 2014 11:00       1

 

 

 

Specify the Begin and End Snapshot Ids

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Enter value for begin_snap: 533

Begin Snapshot Id specified: 533

 

Enter value for end_snap: 534

End   Snapshot Id specified: 534

 

 

 

 

Specify the SQL Id

~~~~~~~~~~~~~~~~~~

Enter value for sql_id: cshvm6ngravw0

SQL ID specified:  cshvm6ngravw0

 

Specify the Report Name

~~~~~~~~~~~~~~~~~~~~~~~

The default report file name is awrsqlrpt_1_533_534.html.  To use this name,

press to continue, otherwise enter an alternative.

 

Enter value for report_name:

 

Using the report name awrsqlrpt_1_533_534.html

 
--以下為生成的報告的內容:

WORKLOAD REPOSITORY SQL Report

Snapshot Period Summary

DB Name

DB Id

Instance

Inst num

Release

RAC

Host

ORCL

1347935162

orcl

1

10.2.0.5.0

NO

localhost.localdomain

Snap Id

Snap Time

Sessions

Cursors/Session

Begin Snap:

533

27-Apr-14 09:59:56

22

2.1

End Snap:

534

27-Apr-14 11:00:57

22

4.0

Elapsed:

 

61.02 (mins)

 

 

DB Time:

 

0.10 (mins)

 

 

SQL Summary

SQL Id

Elapsed Time (ms)

Module

Action

SQL Text

cshvm6ngravw0

68

SQL*Plus

 

SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18, 19)...


Back to Top

SQL ID: cshvm6ngravw0

#

Plan Hash Value

Total Elapsed Time(ms)

Executions

1st Capture Snap ID

Last Capture Snap ID

1

128660979

68

1

534

534


Back to Top

Plan 1(PHV: 128660979)

Back to Top

Plan Statistics

  • % Total DB Time is the Elapsed Time of the SQL statement divided into the Total Database Time multiplied by 100

Stat Name

Statement Total

Per Execution

% Snap Total

Elapsed Time (ms)

68

67.82

1.10

CPU Time (ms)

45

44.99

1.36

Executions

1

 

 

Buffer Gets

225

225.00

0.10

Disk Reads

0

0.00

0.00

Parse Calls

1

1.00

0.01

Rows

2

2.00

 

User I/O Wait Time (ms)

0

 

 

Cluster Wait Time (ms)

0

 

 

Application Wait Time (ms)

0

 

 

Concurrency Wait Time (ms)

0

 

 

Invalidations

0

 

 

Version Count

1

 

 

Sharable Mem(KB)

27

 

 

Back to Plan 1(PHV: 128660979) 
Back to Top

Execution Plan

Id

Operation

Name

Rows

Bytes

Cost (%CPU)

Time

0

SELECT STATEMENT

 

 

 

8 (100)

 

1

   TABLE ACCESS BY INDEX ROWID

T2

1

2041

2 (0)

00:00:01

2

     NESTED LOOPS

 

2

4198

8 (0)

00:00:01

3

       INLIST ITERATOR

 

 

 

 

 

4

         TABLE ACCESS BY INDEX ROWID

T1

2

116

4 (0)

00:00:01

5

           INDEX RANGE SCAN

T1_N

2

 

2 (0)

00:00:01

6

       INDEX RANGE SCAN

T2_T1_ID

1

 

1 (0)

00:00:01



  • dynamic sampling used for this statement

Back to Plan 1(PHV: 128660979) 
Back to Top

Full SQL Text

SQL Id

SQL Text

cshvm6ngravw0

SELECT * FROM t1, t2 WHERE t1.id = t2.t1_id AND t1.n in(18, 19)


Back to Top

 

特點:1SQL語句只有被執行過,才能得到其執行計劃。

      2、可以看到已經從SHARED_POOL中被清除的執行計劃。

      3、看不到謂詞資訊。

綜上,對各種獲取執行計劃的方法適用場景歸納如下:

1.  如果某SQL執行時間較長,而又需要儘快看到執行計劃,可以用explain plan fordbms_xplan.display_cursor指定SQL_ID的方法;

       2. 跟蹤某條SQL最簡單的方法是explain plan for,其次就是set autotrace on

3. 如果想觀察到某條SQL有多條執行計劃的情況,應使用dbms_xplan.display_cursor指定SQL_IDCHILD_NUMBER的方法和檢視指定SQL_ID語句的AWR報告的方法;

4. 如果SQL中含有多函式,函式中套有SQL等多層遞迴呼叫,想準確分析,應使用10046跟蹤事件的方法;

       5要想獲取表被訪問的次數,應使用設定會話選項為statistics_level=all後,用dbms_xplan.display_cursor(null,null,allstats last)檢視執行計劃的方法;


上述方法中,哪些才能獲得真實的執行計劃?

顧名思義,只有被真正執行過的SQL,其所對應的執行計劃才是真實的,反之,則不能保證你所看到的執行計劃與真實執行時所採用的執行計劃相同。
因此,上述方法中
1、explain for ... 
不能保證獲取到真正的執行計劃

而剩下的四種方法:
2、set autotrace on
3、 dbms_xplan.display_cursor
4、 10046 trace跟蹤
5、 awrsqrpt.sql
都可以獲得真實的執行計劃。但有一點需要注意,如果SQL中包含有繫結變數,那麼用set autotrace on方法所獲取到的執行計劃,也有可能不是真實的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21251711/viewspace-2120217/,如需轉載,請註明出處,否則將追究法律責任。

相關文章