如何获取执行计划

执行计划是DBA诊断问题常用的辅助工具,利用执行计划我们可以发现资源是如何消耗的或者优化器是否选择了正确的执行路径。获取执行计划的方式总体上来书可以分为两类:

  1. EXPLAIN PLAN  - 通过该命令生成sql语句的执行计划,但是该语句并没有真正执行
  2. 字典视图- 通过oracle字典视图我们可以查询缓存在内存中的已经执行的sql语句的执行计划.

在某些情况下,通过explain plan和查询字典视图获取的执行计划是不同的,例如在存在绑定变量时,两者的处理方式就会存在差异,下面我们会一一讨论。在oracle9i后,通过功能不断强化的plsql包,我们可以非常容易的查询执行计划,并且获取执行计划的方式也是多种多样,例如我们可以从如下位置获取执行计划:
  1. EXPLAIN PLAN command
  2. V$SQL_PLAN
  3. Automatic Workload Repository (AWR)
  4. SQL Tuning Set (STS)
  5. SQL Plan Baseline (SPM)

使用EXPLAIN PLAN

SQL> explain plan for select count(*) from products;

已解释。

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

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
Plan hash value: 589338964

------------------------------------------------------------------
| Id  | Operation		      | Name			 |
------------------------------------------------------------------
|   0 | SELECT STATEMENT	      | 			 |
|   1 |  SORT AGGREGATE 	      | 			 |
|   2 |   BITMAP CONVERSION COUNT     | 			 |
|   3 |    BITMAP INDEX FAST FULL SCAN| PRODUCTS_PROD_STATUS_BIX |
------------------------------------------------------------------

已选择10行。

如果使用绑定变量,explain plan的输出结果

SQL> var v number
SQL> exec :v := 145

PL/SQL 过程已成功完成。

SQL> explain plan for select count(*) from products where prod_id = :v;

已解释。

SQL> select * from table(dbms_xplan.display('','','TYPICAL +PEEKED_BINDS'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
Plan hash value: 2065297493

----------------------------------------------------------------------------------
| Id  | Operation	   | Name	 | Rows  | Bytes | Cost (%CPU)| Time	 |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |		 |     1 |     4 |     0   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |		 |     1 |     4 |	      | 	 |
|*  2 |   INDEX UNIQUE SCAN| PRODUCTS_PK |     1 |     4 |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
---------------------------------------------------

   2 - access("PROD_ID"=TO_NUMBER(:V))  --进行了类型转换

已选择14行。

从上面可以看出,explain plan对绑定变量不仅仅没有执行BIND PEEKING ,而且进行了数据类型转换,只是因为explain plan始终认为绑定变量为varchar2类型


使用V$SQL_PLAN

通过DBMS_XPLAN.DISPLAY_CURSOR我们可以访问存放在V$SQL_PLAN 中的执行计划,语法格式如下

FUNCTION DISPLAY_CURSOR RETURNS DBMS_XPLAN_TYPE_TABLE
参数名称		       类型		       输入/输出默认值?
------------------------------ ----------------------- ------ --------
 SQL_ID 			VARCHAR2		IN     DEFAULT
 CURSOR_CHILD_NO		NUMBER(38)		IN     DEFAULT
 FORMAT 			VARCHAR2		IN     DEFAULT

如果省略SQL_ID,CURSOR_CHILD_NO则默认查询当前session中最后执行的sql执行计划

SQL> var v number
SQL> exec :v := 144

PL/SQL 过程已成功完成。

SQL> select count(*) from products where prod_id = :v;

  COUNT(*)
----------
	 1

SQL> select * from table(dbms_xplan.display_cursor('','','typical +PEEKED_BINDS'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID	9gnda3r7m7jvw, child number 0
-------------------------------------
select count(*) from products where prod_id = :v

Plan hash value: 2065297493

-----------------------------------------------------------------------
| Id  | Operation	   | Name	 | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------
|   0 | SELECT STATEMENT   |		 |	 |	 |     1 (100)|
|   1 |  SORT AGGREGATE    |		 |     1 |     4 |	      |

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
|*  2 |   INDEX UNIQUE SCAN| PRODUCTS_PK |     1 |     4 |     0   (0)|
-----------------------------------------------------------------------

Peeked Binds (identified by position):
--------------------------------------

   1 - :V (NUMBER): 144   --在EXPLAIN PLAN时,是没有该段内容的

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


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
   2 - access("PROD_ID"=:V)


已选择24行。

通过AWR

与通过v$sql_plan相似,也可以通过awr来获取执行计划,采用的过程时DBMS_XPLAN.DISPLAY_AWR(),该函数的语法格式如下:

FUNCTION DISPLAY_AWR RETURNS DBMS_XPLAN_TYPE_TABLE
参数名称		       类型		       输入/输出默认值?
------------------------------ ----------------------- ------ --------
 SQL_ID 			VARCHAR2		IN
 PLAN_HASH_VALUE		NUMBER(38)		IN     DEFAULT
 DB_ID				NUMBER(38)		IN     DEFAULT
 FORMAT 			VARCHAR2		IN     DEFAULT
示例如下:

SQL> select * from table(dbms_xplan.display_awr('1v44r7vam2wbt'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 1v44r7vam2wbt
--------------------
delete from WRH$_IOSTAT_FUNCTION tab where (:beg_snap <= tab.snap_id
and	    tab.snap_id <= :end_snap and	 dbid = :dbid)	  and
not exists (select 1 from WRM$_BASELINE b		     where
(tab.dbid = b.dbid) and 			 (tab.snap_id >=
b.start_snap_id) and			      (tab.snap_id <=
b.end_snap_id))

Plan hash value: 1772041547


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------
| Id  | Operation		       | Name			 | Rows  | Bytes | Cost (%CPU)| Time	 |
----------------------------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT	       |			 |	 |	 |     4 (100)| 	 |
|   1 |  DELETE 		       | WRH$_IOSTAT_FUNCTION	 |	 |	 |	      | 	 |
|   2 |   FILTER		       |			 |	 |	 |	      | 	 |
|   3 |    INDEX RANGE SCAN	       | WRH$_IOSTAT_FUNCTION_PK |     1 |    17 |     2   (0)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| WRM$_BASELINE		 |     1 |    33 |     2   (0)| 00:00:01 |
|   5 |      INDEX RANGE SCAN	       | WRM$_BASELINE_PK	 |     1 |	 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------


已选择22行。


通过sqlplanbaseline

通过sqlplan baseline,也可以获取执行计划。sqlplan baseline是在11g中引入的新技术,主要用来支持SPM。下面看一下如何通过sqlplan baseline来获取执行计划。

SQL> alter session set optimizer_capture_sql_plan_baselines=true;

会话已更改。

SQL> select count(*) from t1;

  COUNT(*)
----------
     74008

SQL> /

  COUNT(*)
----------
     74008

SQL> select sql_handle,plan_name,accepted from dba_sql_plan_baselines where sql_text like 'select count(*) from t1';

SQL_HANDLE		       PLAN_NAME		      ACC
------------------------------ ------------------------------ ---
SQL_e208a16bb98b6a04	       SQL_PLAN_f4251dfwsquh4dcd11e45 YES

SQL> select * from table(dbms_xplan.display_sql_plan_baseline('SQL_e208a16bb98b6a04'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------
SQL handle: SQL_e208a16bb98b6a04
SQL text: select count(*) from t1
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
Plan name: SQL_PLAN_f4251dfwsquh4dcd11e45	  Plan id: 3704692293
Enabled: YES	 Fixed: NO	Accepted: YES	  Origin: AUTO-CAPTURE
--------------------------------------------------------------------------------


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 129980005

----------------------------------------------------------------------
| Id  | Operation	      | Name | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |	   1 |	  46   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE       |      |	   1 |		  |	     |
|   2 |   INDEX FAST FULL SCAN| I1   | 74008 |	  46   (0)| 00:00:01 |
----------------------------------------------------------------------

已选择20行。




<think>嗯,用户问的是关于Oracle获取执行计划的方法,我需要详细介绍一下。首先,我得回想一下Oracle中常用的几种获取执行计划的方式,比如EXPLAIN PLAN命令、AUTOTRACE、DBMS_XPLAN包,还有SQL*Plus里的那些工具。可能还需要提到动态性能视图,比如V$SQL_PLAN。 用户可能是数据库开发人员或者DBA,他们需要优化SQL查询性能,所以执行计划对他们来说很重要。他们可能已经知道执行计划的基本概念,但需要具体的操作步骤和不同方法的区别。我需要分清楚每种方法的适用场景,比如实时执行计划和历史执行计划的不同获取方式。 还要注意不同Oracle版本的差异,比如DBMS_XPLAN在9i之后才有,而12c可能有一些新功能。要确保提供的方法适用于大多数版本,或者至少指出版本要求。可能用户在使用某些工具时遇到权限问题,比如AUTOTRACE需要PLUSTRACE角色,这时候需要提醒他们如何授权。 另外,是否需要举例说明?比如,用具体的例子展示如何运行EXPLAIN PLAN然后查询计划表,或者如何使用DBMS_XPLAN.DISPLAY。用户可能希望看到实际的SQL语句,这样更容易理解操作步骤。 可能还需要解释执行计划中的关键部分,比如操作顺序、访问路径、连接方式、预估行数和成本。这样用户不仅能获取执行计划,还能理解其内容以进行优化。另外,实时监控执行计划的方法,比如用GV$SQL_PLAN_MONITOR,可能对分析长时间运行的查询有帮助。 需要注意的是,某些方法可能需要实际执行SQL,比如使用AUTOTRACE的STATISTICS级别,而EXPLAIN PLAN只是解析而不执行。这点差异对生产环境可能有影响,需要提醒用户谨慎操作,避免对生产数据造成影响。 最后,确保语言简洁明了,分点列出各个方法,每个方法的步骤、使用场景和注意事项。可能还需要比较不同方法的优缺点,帮助用户选择最适合他们情况的方式。例如,AUTOTRACE方便快捷,而DBMS_XPLAN更灵活,可以显示更多详细信息。</think>在 Oracle 数据库中,**执行计划(Execution Plan)**是优化器(Optimizer)为 SQL 语句生成的执行路径说明,用于分析 SQL 性能问题。以下是获取执行计划的常用方法: --- ### **1. 使用 `EXPLAIN PLAN` 命令** **适用场景**:离线分析,无需实际执行 SQL。 ```sql -- 步骤1: 生成执行计划 EXPLAIN PLAN FOR SELECT * FROM employees WHERE department_id = 10; -- 步骤2: 查询计划表(默认表为 PLAN_TABLE) SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY()); ``` **关键输出**: - **Operation**:执行步骤(如 `TABLE ACCESS FULL`)。 - **Name**:操作对象(如表名、索引名)。 - **Rows**:预估行数。 - **Cost**:优化器计算的成本。 --- ### **2. 使用 `AUTOTRACE`(SQL*Plus 或 SQLcl)** **适用场景**:即时查看执行计划和统计信息。 ```sql -- 开启 AUTOTRACE(需有 PLUSTRACE 角色权限) SET AUTOTRACE ON EXPLAIN; -- 仅显示执行计划 SET AUTOTRACE ON STATISTICS; -- 显示执行计划 + 统计信息(需实际执行 SQL) ``` **示例输出**: ``` Execution Plan ---------------------------------------------------------- Plan hash value: 123456789 | Id | Operation | Name | Rows | Cost | |-----|--------------------|-----------|-------|------| | 0 | SELECT STATEMENT | | 10 | 2 | | 1 | TABLE ACCESS FULL | EMPLOYEES | 10 | 2 | ``` --- ### **3. 使用 `DBMS_XPLAN` 包** **适用场景**:灵活获取执行 SQL计划(需 SQL 已运行)。 ```sql -- 方法1:根据 SQL_ID 获取(需查询 V$SQL) SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', child_number)); -- 方法2:直接获取最近执行计划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR()); ``` **适用版本**:Oracle 9i+。 --- ### **4. 动态性能视图** 通过 `V$SQL_PLAN` 或 `GV$SQL_PLAN` 查看已执行 SQL计划: ```sql SELECT * FROM V$SQL_PLAN WHERE SQL_ID = 'your_sql_id'; ``` --- ### **5. 实时监控(Oracle 12c+)** 使用 `DBMS_SQL_MONITOR` 监控长时间运行的 SQL: ```sql SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR(sql_id => 'your_sql_id') FROM DUAL; ``` --- ### **执行计划关键点** 1. **访问路径**:如 `FULL TABLE SCAN`(全表扫描)或 `INDEX RANGE SCAN`(索引范围扫描)。 2. **连接方式**:`HASH JOIN`、`NESTED LOOPS` 或 `MERGE JOIN`。 3. **预估 vs 实际**:对比 `Rows`(预估)与执行后的 `A-Rows`(实际行数)。 4. **执行顺序**:从内层到外层(缩进越深,执行越早)。 --- ### **注意事项** - **权限要求**:部分方法需要 `SELECT_CATALOG_ROLE` 或 `DBA` 权限。 - **绑定变量**:实际执行计划可能受绑定变量影响。 - **统计信息**:确保表/索引的统计信息最新,否则优化器可能生成低效计划。 通过分析执行计划,可以定位 SQL 性能瓶颈(如全表扫描、高成本操作),进而优化索引或改写 SQL
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值