程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> sql-查看執行計劃的方法,sql-查看執行計劃

sql-查看執行計劃的方法,sql-查看執行計劃

編輯:Oracle教程

sql-查看執行計劃的方法,sql-查看執行計劃


sql執行計劃:把SQL語句拆分為每個的操作步驟組合,按照一定的順序執行得出結果,查看並看懂執行計劃是調優的關鍵步驟

查看執行計劃的方法

  • DBMS_XPLAN包
  • sql*plus AUTO trace
  • V$SQL_PLAN、DBA_HIST_SQL_PLAN
  • ?/rdbms/admin/awrsqrpt.sql
  • 工具類:toad、pl/SQL DEV
  • 跟蹤dump:10046,10053

大多數人比較喜歡用工具直接看,以下來說明這些方式的不同用處


一、DBMS_XPLAN包

10g以後可以查看AWR中的語句執行計劃,也可以查看當前內存中游標的執行計劃。

主要有以下五個方法:

  • DISPLAY - 格式化並顯示plan table中內容,類似工具的F5(EXPLAIN PLAN FOR …)

  • DISPLAY_AWR -格式和顯示存儲在AWR中的SQL語句的執行計劃。數據來源: DBA_HIST_SQL_PLAN,DBA_HIST_SQLTEXT

  • DISPLAY_CURSOR -格式和顯示任何加載游標執行計劃的內容。數據來源:V$SQL_PLAN和V$SQL_PLAN_STATISTICS_ALL

  • DISPLAY_SQL_PLAN_BASELINE - 顯示一個或多個執行計劃的SQL語句通過SQL handle 標識 。數據來源:DBA_SQL_PLAN_BASELINES

  • DISPLAY_SQLSET - 格式和顯示存儲在sql調優集中的執行計劃內容。數據來源:ALL_SQLSET_STATEMENTS、ALL_SQLSET_PLANS

 

最常用的DISPLAY_AWR和DISPLAY_CURSOR,來闡述具體的調用方式,顯示的內容

(一)、DISPLAY_CURSOR

顯示當前shared pool->library cache中的執行計劃

DBMS_XPLAN.DISPLAY_CURSOR(
   sql_id            IN  VARCHAR2  DEFAULT  NULL,
   cursor_child_no   IN  NUMBER    DEFAULT  0, 
   format            IN  VARCHAR2  DEFAULT  'TYPICAL');
參數 說明(常用說明) sql_id SQL的唯一標識,取SELECT SQL_ID FROM V$SQL,為null的情況下,取上一條語句的執行計劃 cursor_child_no 子游標的id號,為null,取出全部子游標的執行計劃 format 輸出格式化
默認TYPICAL
ADVANCED +PEEKED_BINDS
ALLSTATS

例子查看

#默認格式輸出
select * from  table(dbms_xplan.display_cursor('bjqjt2dfvya84',null))

SQL_ID  bjqjt2dfvya84, child number 0
-------------------------------------
select * from emp where empno=7521

Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
--------------------------------------------------------------------------------------

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

   2 - access("EMPNO"=7521)

#格式化為ADVANCED +PEEKED_BINDS
select * from  table(dbms_xplan.display_cursor('bjqjt2dfvya84',null,'ADVANCED +PEEKED_BINDS'))

SQL_ID  bjqjt2dfvya84, child number 0
-------------------------------------
select * from emp where empno=7521

Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
--------------------------------------------------------------------------------------

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

   1 - SEL$1 / EMP@SEL$1
   2 - SEL$1 / EMP@SEL$1

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

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      OPT_PARAM('optimizer_dynamic_sampling' 0)
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "EMP"@"SEL$1" ("EMP"."EMPNO"))
      END_OUTLINE_DATA
  */

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

   2 - access("EMPNO"=7521)

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

   1 - "EMPNO"[NUMBER,22], "EMP"."ENAME"[VARCHAR2,10],
       "EMP"."JOB"[VARCHAR2,9], "EMP"."MGR"[NUMBER,22], "EMP"."HIREDATE"[DATE,7],
       "EMP"."SAL"[NUMBER,22], "EMP"."COMM"[NUMBER,22], "EMP"."DEPTNO"[NUMBER,22]
   2 - "EMP".ROWID[ROWID,10], "EMPNO"[NUMBER,22]

#格式化ALLSTATS
兩種處理方式: * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
select /*+gather_plan_statistics*/  * from emp where empno=7521

select * from  table(dbms_xplan.display_cursor('dvj95t2z1gh2a',null,'ALLSTATS'))

SQL_ID  dvj95t2z1gh2a, child number 0
-------------------------------------
select /*+gather_plan_statistics*/  * from emp where empno=7521

Plan hash value: 2949544139

------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |      1 |        |      1 |00:00:00.01 |       2 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |      1 |      1 |      1 |00:00:00.01 |       1 |
------------------------------------------------------------------------------------------------

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

   2 - access("EMPNO"=7521)

A-ROW是實際的行數,E-ROW是優化器評估的

 

(二)、DISPLAY_AWR

顯示AWR中的SQL的執行計劃,對分析歷史SQL慢的相當有幫組

DBMS_XPLAN.DISPLAY_AWR(
   sql_id            IN      VARCHAR2,
   plan_hash_value   IN      NUMBER DEFAULT NULL,
   db_id             IN      NUMBER DEFAULT NULL,
   format            IN      VARCHAR2 DEFAULT TYPICAL);
參數 常用說明 SQL_ID SQL的唯一標識,取SELECT SQL_ID FROM DBA_HIST_SQLTEXT PLAN_HASH_VALUE 指定SQL語句的PLAN_HASH_VALUE,忽略取全部的SQL_ID下的執行計劃 DB_ID 默認取V$DATABASE.DATABASE_ID FORMAT 輸出格式化
默認TYPICAL
ADVANCED +PEEKED_BINDS

例子查看

#默認輸出的格式
select * from  table(dbms_xplan.display_awr('bjqjt2dfvya84'));

SQL_ID bjqjt2dfvya84
--------------------
select * from emp where empno=7521

Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|   2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
--------------------------------------------------------------------------------------


#通過格式化ADVANCED +PEEKED_BINDS
select * from  table(dbms_xplan.display_awr('bjqjt2dfvya84',FORMAT=>'ADVANCED +PEEKED_BINDS'));
SQL_ID bjqjt2dfvya84
--------------------
select * from emp where empno=7521

Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|   2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)|          |
--------------------------------------------------------------------------------------

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

   1 - SEL$1 / EMP@SEL$1
   2 - SEL$1 / EMP@SEL$1

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

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      OPT_PARAM('optimizer_dynamic_sampling' 0)
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "EMP"@"SEL$1" ("EMP"."EMPNO"))
      END_OUTLINE_DATA
  */



 


二、sqlplus  autotrace

scott@GULL> set autotrace
用法: SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]]

可以體現執行語句的執行計劃和統計信息

scott@GULL> SET autotrace  trace
scott@GULL> select * from emp where empno=7521;


執行計劃
----------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    38 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

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

   2 - access("EMPNO"=7521)


統計信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        902  bytes sent via SQL*Net to client
        508  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

scott@GULL>

 


三、V$SQL_PLAN

直接取數據字典的源數據

scott@GULL> col id format 99;
scott@GULL> col parent_id format 99999;
scott@GULL> col operation format a25;
scott@GULL> col options format a20;
scott@GULL> select id,parent_id,operation,options from V$SQL_PLAN where sql_id='bjqjt2dfvya84';

 ID PARENT_ID OPERATION                 OPTIONS
--- --------- ------------------------- --------------------
  0           SELECT STATEMENT
  1         0 TABLE ACCESS              BY INDEX ROWID
  2         1 INDEX                     UNIQUE SCAN

 


四、?/rdbms/admin/awrsqrpt.sql

查看AWR中執行計劃,調用這個腳本後,相關的直觀展現

scott@GULL> @?/rdbms/admin/awrsqrpt.sql

Current Instance
~~~~~~~~~~~~~~~~

   DB Id    DB Name      Inst Num Instance
----------- ------------ -------- ------------
 3239200222 GULL                1 gullstby


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'
輸入 report_type 的值:  html

Type Specified:  html


Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   DB Id     Inst Num DB Name      Instance     Host
------------ -------- ------------ ------------ ------------
* 3239200222        1 GULL         gullstby     gull02

Using 3239200222 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 <return> without
specifying a number lists all completed snapshots.


輸入 num_days 的值:  1

Listing the last day's Completed Snapshots

                                                        Snap
Instance     DB Name        Snap Id    Snap Started    Level
------------ ------------ --------- ------------------ -----
gullstby     GULL               368 01 6月  2016 10:08     1
                                369 01 6月  2016 10:12     1



Specify the Begin and End Snapshot Ids
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
輸入 begin_snap 的值:  368
Begin Snapshot Id specified: 368

輸入 end_snap 的值:  369
End   Snapshot Id specified: 369




Specify the SQL Id
~~~~~~~~~~~~~~~~~~
輸入 sql_id 的值:  bjqjt2dfvya84
SQL ID specified:  bjqjt2dfvya84

Specify the Report Name
~~~~~~~~~~~~~~~~~~~~~~~
The default report file name is awrsqlrpt_1_368_369.html.  To use this name,
press <return> to continue, otherwise enter an alternative.

輸入 report_name 的值:  /home/oracle/0601.html
 
 

 

 

 


五、工具類:toad(ctrl+e)、pl/SQL DEV(f5)

工具類查看執行計劃,非常快捷、簡單、能清楚知道每部步驟的優先級,但是他們實際調用的是EXPLAIN PLAN for,寫入plan_TABLE,是優化器的預評估,不是正在SQL執行時的執行計劃。簡單分析是有用的,但是在你的應用程序中SQL很慢,常用的SQL用toad等很快,此時就不要在用工具快捷方式去查看執行計劃,要去分析正在執行的執行計劃,采用以上的內容方式。

toad(ctrl+e)

SQL> conn /as sysdba 已連接。 SQL> ALTER SESSION SET EVENTS '10046 trace name context forever, level 28'; 會話已更改。 SQL> select * from scott.emp where empno=7521; SQL> select c.value || '/' || d.instance_name || '_ora_' || 2 a.spid || '.trc' || 3 case when e.value is not null then '_'||e.value end trace 4 from v$process a, v$session b, v$parameter c, v$instance d, v$parameter e 5 where a.addr = b.paddr 6 and b.sid = userenv('sid') 7 and c.name = 'user_dump_dest' 8 and e.name = 'tracefile_identifier'; TRACE -------------------------------------------------------------------------------- /u01/app/oracle/diag/rdbms/orclstby/orcl/trace/orcl_ora_3288.trc

 
查看日志文件的內容
....
PARSING IN CURSOR #139774981787448 len=41 dep=0 uid=0 oct=3 lid=0 tim=1464851500943287 hv=3602254372 ad='d4180e00' sqlid='89mgdagbbc2j4'
select * from scott.emp where empno=7521
END OF STMT
PARSE #139774981787448:c=60990,e=224928,p=20,cr=444,cu=0,mis=1,r=0,dep=0,og=1,plh=2949544139,tim=1464851500943287
EXEC #139774981787448:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2949544139,tim=1464851500943287
WAIT #139774981787448: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=5473 tim=1464851500943295
WAIT #139774981787448: nam='Disk file operations I/O' ela= 29 FileOperation=2 fileno=4 filetype=2 obj#=75336 tim=1464851500943586
WAIT #139774981787448: nam='db file sequential read' ela= 11120 file#=4 block#=155 blocks=1 obj#=75336 tim=1464851500954730
WAIT #139774981787448: nam='db file sequential read' ela= 428 file#=4 block#=151 blocks=1 obj#=75335 tim=1464851500955277
FETCH #139774981787448:c=0,e=12010,p=2,cr=2,cu=0,mis=0,r=1,dep=0,og=1,plh=2949544139,tim=1464851500955332
STAT #139774981787448 id=1 cnt=1 pid=0 pos=1 obj=75335 op='TABLE ACCESS BY INDEX ROWID EMP (cr=2 pr=2 pw=0 time=11994 us cost=1 size=38 card=1)'
STAT #139774981787448 id=2 cnt=1 pid=1 pos=1 obj=75336 op='INDEX UNIQUE SCAN PK_EMP (cr=1 pr=1 pw=0 time=11487 us cost=0 size=0 card=1)'
WAIT #139774981787448: nam='SQL*Net message from client' ela= 297 driver id=1650815232 #bytes=1 p3=0 obj#=75335 tim=1464851500955736
FETCH #139774981787448:c=0,e=2,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=2949544139,tim=1464851500955773
WAIT #139774981787448: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=75335 tim=1464851500955791
采用tkprof格式化10046,看起來更加的清晰
[oracle@gull2 ~]$ tkprof /u01/app/oracle/diag/rdbms/orclstby/orcl/trace/orcl_ora_3288.trc /home/oracle/3288.trc
查看3288.trc
SQL ID: 89mgdagbbc2j4 Plan Hash: 2949544139

select *afrom scott.emp where empno=7521


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.06       0.22          0        444          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.01          2          2          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.06       0.23          2        446          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  TABLE ACCESS BY INDEX ROWID EMP (cr=2 pr=2 pw=0 time=11994 us cost=1 size=38 card=1)
         1          1          1   INDEX UNIQUE SCAN PK_EMP (cr=1 pr=1 pw=0 time=11487 us cost=0 size=0 card=1)(object id 75336)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net break/reset to client                   2        0.00          0.00
  SQL*Net message to client                       3        0.00          0.00
  SQL*Net message from client                     2       11.43         11.43
  Disk file operations I/O                        1        0.00          0.00
  db file sequential read                         2        0.01          0.01

六、10053

10053這個事件是查看為什麼SQL語句評估出發的執行計劃是這樣的,優化器如何評估出來這個執行計劃的,記錄優化器的計算值

SQL> conn /as sysdba
已連接。
SQL>  oradebug setmypid;
已處理的語句
SQL>  oradebug event 10053 trace name context forever ,level 1;
已處理的語句
SQL>  select * from  scott.emp   where    empno=7521;

     EMPNO ENAME                          JOB                                MGR
---------- ------------------------------ --------------------------- ----------
HIREDATE              SAL       COMM     DEPTNO
-------------- ---------- ---------- ----------
      7521 WARD                           SALESMAN                          7698
22-2月 -81           1250        500         30


SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orclstby/orcl/trace/orcl_ora_9109.trc
.......
Starting SQL statement dump

user_id=0 user_name=SYS module=sqlplus@gull2 (TNS V1-V3) action=
sql_id=b250dw0hyz0rs plan_hash_value=-1345423157 problem_type=3
----- Current SQL Statement for this session (sql_id=b250dw0hyz0rs) -----
 select * from  scott.emp   where    empno=7521
sql_text_length=49
sql= select * from  scott.emp   where    empno=7521
----- Explain Plan Dump -----
----- Plan Table -----

============
Plan Table
============
-----------------------------------------------+-----------------------------------+
| Id  | Operation                    | Name    | Rows  | Bytes | Cost  | Time      |
-----------------------------------------------+-----------------------------------+
| 0   | SELECT STATEMENT             |         |       |       |     1 |           |
| 1   |  TABLE ACCESS BY INDEX ROWID | EMP     |     1 |    38 |     1 |  00:00:01 |
| 2   |   INDEX UNIQUE SCAN          | PK_EMP  |     1 |       |     0 |           |
-----------------------------------------------+-----------------------------------+
Predicate Information:
----------------------
2 - access("EMPNO"=7521)

Content of other_xml column
===========================
  db_version     : 11.2.0.3
  parse_schema   : SYS
  plan_hash      : 2949544139
  plan_hash_2    : 1767686164
  Outline Data:
  /*+
    BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "EMP"@"SEL$1" ("EMP"."EMPNO"))
    END_OUTLINE_DATA
  */

 


總結

1、查看真實的執行計劃,使用DBMS_XPLAN.DISPLAY_CUROR這個過程,可以清晰的展示SHARED_POOL-》libarary中的執行計劃,不需要你重新去運行SQL語句,根據不同的格式輸出你需要的內容,可以查看出統計信息是否陳舊、謂詞中的字段類型是否有隱式轉化(導致索引不能使用)等

2、DBMS_XPLAN.DISPLAY_AWR,查看AWR中的執行計劃,是否存在多個執行計劃,代價比較高-》消耗性能厲害的,更加直觀的可以調用?/rdbms/admin/awrsqrpt.sql

3、sql*plus autotrace 需要重新去運行一遍SQL語句,查看現在運行的這個語句的執行計劃,無法查看到,你程序中運行的那條語句的執行計劃

4、工具調用(如toad 、PL/SQL DEV),實際采用的EXPLAIN PLAN FOR... 保存到plan_TABLE,是優化器的預評估。

5、10046的事件使用的范圍在調試一個語句執行很慢,想清楚具體等待的是什麼,慢在哪個階段,還可以查看一些DDL的語句,內部語句的構造的方式,但查看執行計劃,10046不是特別的方便,需要重新執行SQL語句,到服務器端拿日志文件

6、10053的事件可以用來分析 SQL語句為什麼會做這個執行計劃(如沒有走索引,而是走了全表掃描)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved