生成和显示SQL语句的执行计划,是大多数DBA、SQL开发人员以及性能优化专家经常做的工作,因为执行计划能够提供SQL语句性能相关的信息。执行计划解释了SQL语句执行的详细过程,这个过程记录了一系列的数据库操作以及每个操作涉及到的数据行数和生成的数据行数。优化器使用查询转换和物理优化技术决定数据库操作顺序和过程实现。

执行计划通常以扁平的表格形式呈现,是一个事实树形结构。下面是一个基于SH模式中SALES、PRODUCTS表生成的查询:

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

执行计划以表格的形式呈现:

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

通过事实树来解读执行计划:

GROUP BY
      |
     JOIN
 _____|_______
 |            |
ACCESS     ACCESS
(PRODUCTS) (SALES)

计划树的执行顺序是从下到上,上述的例子中,首先执行的是表的访问操作,也就是树的叶子部分。通过执行计划,我们可以看出访问操作是全表扫描,表扫描返回的数据行用来做连接操作,这里连接操作的类型是hash连接。最后对连接操作返回的数据行进行group-by,这里分组同样使用的是hash。

值得一提的是,查询优化器最终选择的执行计划是从众多的可选择执行计划中选取的代价最低的一个。这里的代价可以理解为性能的衡量指标,代价越低性能越好。查询优化器使用的代价模型是通过评估IO、CPU及网络等方面的数据计算出来的。

Oracle数据库中可以通过两种方式查看SQL语句的执行计划:

EXPLIAN PLAN 命令 — 这种方式没有实际执行SQL语句而仅仅把执行计划显示出来;
V$SQL_PALN — 从Oracle 9i开始引入了这个V$视图,通过该视图可以查询游标缓存中存在的SQL语句的执行计划。

在某些特定的场景下,使用EXPLAIN PLAN得到的执行计划可能和V$SQL_PLAN不同。比如,当SQL语句包含绑定变量时,EXPLAIN PLAN得到的执行计划会忽略绑定变量值,而V$SQL_PLAN中记录的执行计划则考虑了绑定变量值。

Oracle 9i引入了dbms_xplan包,随后的版本中该包的功能不断的增强,使得查看执行计划变得更加便利。这个包里提供了几个PL/SQL函数,用于从不同的数据源获取执行计划:

1. EXPLAIN PLAN command
2. V$SQL_PLAN
3. Automatic Workload Repository (AWR)
4. SQL Tuning Set (STS)
5. SQL Plan Baseline (SPM)

下面通过一些具体的例子展示如果使用dbms_xplan包提供的函数,产生和显示SQL语句的执行计划。

例1:使用EXPLAIN PLAN command和dbms_xplan.display函数

SQL> EXPLAIN PLAN FOR
 2   select prod_category, avg(amount_sold)
 3   from sales s, products p
 4   where p.prod_id = s.prod_id
 5   group by prod_category;

Explained.

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table', null, 'basic'));

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

dbms_xplan.display使用的参数有:

plan table name (默认 'PLAN_TABLE')
statement_id (默认 null),
format (默认 'TYPICAL')

更详细的信息可以查看$ORACLE_HOME/rdbms/admin/dbmsxpln.sql。

例2:生成和显示会话中最后执行的SQL语句的执行计划

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

no rows selected

SQL> select plan_table_output
 2   from table(dbms_xplan.display_cursor(null, null, 'basic'));

——————————————
 Id   Operation              Name
——————————————
   0  SELECT STATEMENT
   1   HASH GROUP BY
   2    HASH JOIN
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL
   5      TABLE ACCESS FULL  SALES
——————————————

dbms_xplan.display_cursor使用的参数有:

SQL ID (默认 null, null意味着当前会话中最后执行的SQL语句)
child number (默认 0),
format (默认 'TYPICAL')

例3:显示任何其他语句的执行计划

直接提供SQL_ID:

SQL> select plan_table_output from
 2   table(dbms_xplan.display_cursor('fnrtqw9c233tt',null,'basic'));

间接查询获取SQL_ID:

SQL> select plan_table_output
 2   from v$sql s,
 3   table(dbms_xplan.display_cursor(s.sql_id,
 4                                  s.child_number, 'basic')) t
 5   where s.sql_text like 'select PROD_CATEGORY%';

例4:根据SQL Plan Baseline显示执行计划。SQL Plan Baseline是Oracle 11g中引入的新概念,用于支持SQL Plan Management (SPM)特性。

SQL> alter session set optimizer_capture_sql_plan_baselines=true;

Session altered.

SQL> select prod_category, avg(amount_sold)
 2   from sales s, products p
 3   where p.prod_id = s.prod_id
 4   group by prod_category;

no rows selected

假如上述语句执行超过一次,将会产生一个该语句的SQL Plan Baseline,可以通过下面的查询进行确认:

SQL> select SQL_HANDLE, PLAN_NAME, ACCEPTED
 2   from dba_sql_plan_baselines
 3   where sql_text like 'select prod_category%';

SQL_HANDLE                     PLAN_NAME                      ACC
—————————— —————————— —
SYS_SQL_1899bb9331ed7772       SYS_SQL_PLAN_31ed7772f2c7a4c2  YES

上面创建的SQL Plan Baseline可以通过下面的方式显示:

直接提供SQL_HANDLE:

SQL> select t.* from
 2   table(dbms_xplan.display_sql_plan_baseline('SYS_SQL_1899bb9331ed7772',
 3                                              format => 'basic')) t;

间接查询获取SQL_HANDLE:

SQL> select t.*
 2       from (select distinct sql_handle
 3             from dba_sql_plan_baselines
 4             where sql_text like 'select prod_category%') pb,
 5       table(dbms_xplan.display_sql_plan_baseline(pb.sql_handle,
 6                                                  null,'basic')) t;

这两条语句的输出结果如下:

—————————————————————————-
SQL handle: SYS_SQL_1899bb9331ed7772
SQL text: select prod_category, avg(amount_sold) from sales s, products p
          where p.prod_id = s.prod_id group by prod_category
—————————————————————————-
Plan name: SYS_SQL_PLAN_31ed7772f2c7a4c2
Enabled: YES     Fixed: NO      Accepted: YES     Origin: AUTO-CAPTURE
—————————————————————————-

Plan hash value: 4073170114
———————————————————
 Id   Operation                 Name               
———————————————————
   0  SELECT STATEMENT                             
   1   HASH GROUP BY                               
   2    HASH JOIN                                  
   3     VIEW                   index$_join$_002   
   4      HASH JOIN                                
   5       INDEX FAST FULL SCAN PRODUCTS_PK        
   6       INDEX FAST FULL SCAN PRODUCTS_PROD_CAT_IX
   7     PARTITION RANGE ALL                       
   8      TABLE ACCESS FULL     SALES              
———————————————————

格式化

格式化参数可以进行高度定制,可以根据实际需要输出适当的信息。高级别的选项有:

Basic 输出的执行计划包括操作、选项和对象名(表、索引、物化视图等)
Typical 输出的执行计划包括Basic内容,加上和优化器相关的内部信息,如代价、大小、基数等,具体包括执行计划中的每个操作,优化器计算出来的每个操作的代价,每个操作返回的数据行数等,同时还会包括操作中所使用的评估谓词。Oracle CBO中存在两种谓词:ACCESS和FILTER。ACCESS表示根据查询条件,使用索引提取相关的数据块。FILTER表示数据块提取之后的评估。
All 输出的执行计划包括Typical内容,加上每个操作生成的表达式列表、提示别名、查询块的名称。

低级选项允许包括或者排除诸如谓词、代价之类的细节,举例如下:

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table',null,'basic +predicate +cost'));

——————————————————-
 Id   Operation              Name      Cost (%CPU)
——————————————————-
   0  SELECT STATEMENT                    17  (18)
   1   HASH GROUP BY                      17  (18)
*  2    HASH JOIN                         15   (7)
   3     TABLE ACCESS FULL   PRODUCTS      9   (0)
   4     PARTITION RANGE ALL               5   (0)
   5      TABLE ACCESS FULL  SALES         5   (0)
——————————————————-

Predicate Information (identified by operation id):
—————————————————
2 – access("P"."PROD_ID"="S"."PROD_ID")

select plan_table_output from
table(dbms_xplan.display('plan_table',null,'typical -cost -bytes'));

—————————————————————————-
 Id   Operation              Name      Rows  Time      Pstart Pstop
—————————————————————————-
   0  SELECT STATEMENT                    4  00:00:01             
   1   HASH GROUP BY                      4  00:00:01             
*  2    HASH JOIN                       960  00:00:01             
   3     TABLE ACCESS FULL   PRODUCTS   766  00:00:01             
   4     PARTITION RANGE ALL            960  00:00:01      1     16
   5      TABLE ACCESS FULL  SALES      960  00:00:01      1     16
—————————————————————————-

Predicate Information (identified by operation id):
—————————————————
2 – access("P"."PROD_ID"="S"."PROD_ID")

注解部分

dbms_xplan包生成执行计划时会将注释显示在NOTE部分,比如查询优化过程中使用了动态抽样或者星形转换应用在查询中。比如SALES表没有统计信息,优化器在分析代价时将会使用动态抽样,执行计划将会把这一过程记录在NOTE部分。

SQL> select plan_table_output
 2   from table(dbms_xplan.display('plan_table',null,'basic +note'));

——————————————
 Id   Operation              Name   
——————————————
   0  SELECT STATEMENT              
   1   HASH GROUP BY                
   2    HASH JOIN                   
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL        
   5      TABLE ACCESS FULL  SALES  
——————————————

Note
—–
- dynamic sampling used for this statement

绑定窥视

在生成执行计划时,优化器会考虑绑定变量的实际值,这一过程就是所谓的绑定变量窥视。就像我们前面提到的那样,V$SQL_PLAN中记录的执行计划考虑了绑定变量值而EXPLAIN PLAN命令生成的执行计划并没有考虑这一点。从Oracle10gR2开始,dbms_xplan包可以显示用于生成特定计划或者游标的绑定变量值,只需要在display_cursor()函数时加上'+peeked_binds'参数即可。

下面的例子展示了一点:

SQL> variable pcat varchar2(50)
SQL> exec :pcat := 'Women'

SQL> select PROD_CATEGORY, avg(amount_sold)
 2   from sales s, products p
 3   where p.PROD_ID = s.PROD_ID
 4   and prod_category != :pcat
 5   group by PROD_CATEGORY;

SQL> select plan_table_output
 2   from table(dbms_xplan.display_cursor(null,null,'basic +PEEKED_BINDS'));

——————————————
 Id   Operation              Name   
——————————————
   0  SELECT STATEMENT              
   1   HASH GROUP BY                
   2    HASH JOIN                   
   3     TABLE ACCESS FULL   PRODUCTS
   4     PARTITION RANGE ALL        
   5      TABLE ACCESS FULL  SALES  
——————————————

Peeked Binds (identified by position):
————————————–

1 –  CAT (VARCHAR2(30), CSID=2): 'Women'

Oracle执行计划显示相关推荐

  1. ORACLE 执行计划分析

    http://www.cnblogs.com/rootq/archive/2008/09/06/1285779.html ORACLE 执行计划分析 一.什么是执行计划 An explain plan ...

  2. oracle 执行计划 ppt,oracle查看执行计划的方法

    查看执行计划的方法 Explain Plan For SQL 不实际执行SQL语句,生成的计划未必是真实执行的计划 必须要有plan_table SQLPLUS AUTOTRACE 除set auto ...

  3. 看懂Oracle执行计划(转载)

    转载自 写的很好,屯一波 最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也来总结一下自己最近所学,不定时更新ing- 一:什么是Oracle执行计划? 执行计划是一条查询语句在Or ...

  4. oracle执行计划耗费 基数 字节,Oracle 查看执行计划

    一:什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二:怎样查看Oracle执行计划? 这里以PLSQL为例: ①:配置执行计划需要显示的项: 工具  ...

  5. Oracle 执行计划(Explain Plan)

    执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的 ...

  6. 查看oracle执行计划方法( 一)

    关于oracle执行计划的概念,参考之前的博客:http://blog.csdn.net/cymm_liu/article/details/7996599 如果要分析某条SQL的性能问题,通常我们要先 ...

  7. Oracle总结(一):Oracle执行计划

    看懂Oracle执行计划 最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也来总结一下自己最近所学,不定时更新ing- 1.什么是Oracle执行计划? 执行计划是一条查询语句在Or ...

  8. oracle用plsql trance,Oracle执行计划总结

    一.ORACLE中常见执行计划 表访问的执行计划 1.table access full:全表扫描.它会访问表中的每一条记录. 2.table access by user rowid:输入源rowi ...

  9. Oracle执行计划突变诊断之统计信息收集问题

    Oracle执行计划突变诊断之统计信息收集问题 1.  情形描述 DB version:11.2.0.4 WITH SQL1 AS(SELECT LAC,CI,TO_NUMBER(C.LONGITUD ...

最新文章

  1. centOS怎样强制卸载PHP以及自定义安装PHP
  2. 哪种 Python IDE 最适合你?这里有一份优缺点列表
  3. mysql mtq_MySQL基础知识 - osc_r3mtqivi的个人空间 - OSCHINA - 中文开源技术交流社区
  4. Android 设置TextView字体加粗
  5. 关于Heap Dump
  6. Mybatis映射文件SQL语句模糊查询,#和$的区别和注意事项
  7. 金蝶云系统显示服务器离线,金蝶云服务器已离线是什么情况
  8. C++调用Python函数
  9. 工作304:uni返回上一页面
  10. python缺省参数与多个函数返回值
  11. 卷积神经网络(CNN)相关的基础知识
  12. merge语句_SQL Server MERGE语句概述和示例
  13. Android Studio 3.3功能
  14. 深入理解Java虚拟机--笔记1
  15. 不洗袜子的高文博_那个孩子在夏天中旬用高袜子大笑?
  16. iPhone配置实用工具
  17. vmware workstation网络设置
  18. 学习党Win10装机必备软件
  19. 简述BSD协议和GPL协议的区别
  20. oracle卸数的perl脚本,卸载cpan安装的所有perl模块

热门文章

  1. 利用Python爬取糗事百科段子信息
  2. codeforces 739E - Gosha is hunting
  3. css grid布局
  4. 动态规划-----------01背包,完全背包与多重背包
  5. c++基本类型c++string与c风格字符串的相互转化
  6. Sql Group by 使用
  7. 2.2.2 MySQL基本功能与参数文件管理
  8. nginx-URL重写
  9. idea调试debug技巧_被我用烂的DEBUG调试技巧,专治各种搜索不到的问题
  10. 问题 F: 积木大赛(模拟)