通过 DBMS_XPLAN 输出执行计划,除了计划本身外,我们还可以获得一些其他信息帮助我们进一步分析执行计划及语句性能。
查询块(Query Block)和对象别名(Alias)
在使用 DBMS_XPLAN 显示执行计划时,选择’ADVANCED’预定义格式作为参数或者加入’ALIAS’控制字符串,可以在输出中看到以下内容

其中,数字为对应的操作 ID,SEL$1 为查询块的名字,T@SEL$1 和 O@SEL$1 为查询块中对象的别名。
语句在被提交到 Oracle 后,解析器(Parser)会对 SQL 语句的语法、语义分析,并将查询中的视图展开、划分为小的查询块(Query Block)。这些查询块被传输给优化器后,其查询转换器(Query Transformer)会对它们进行进一步的查询转换,使优化器能生成效率更高的执行计划。
计划纲要(Outline)数据
在使用 DBMS_XPLAN 显示执行计划时,选择’ADVANCED’预定义格式作为参数或者加入’OUTLINE’ 控制字符串,可以在输出中看到以下内容

这是由一组提示(HINT)组成的数据,即执行计划的纲要数据。计划纲要可以确保语句解析出 一个特点的执行计划,换句话说,它能确保语句执行计划的稳定性。在 9i 当中,引入了一个特性: 存储纲要(Stored Outline),作为一个保持语句执行计划稳定的手段:它可以在不中止相关程序、不修改源代码的情况下,影响优化器解析执行计划时的行为。要注意的是,执行计划中的纲要数据是在优化器选择了最终的执行计划后,根据该计划产生的, 用于重现该执行计划的必要的纲要数据。
提示:SQL“提示”(HINT)是内嵌在 SQL 语句中,由/*+ Hint_Words */构成的一段注释。它不会改变语句的逻辑结果,但可以强制优化器在选择执行计划的过程中,使用特定值作为优化参数,或 者选择某些特定的操作作为执行计划的一部分。
在 11g 中,执行计划管理器(SQL Plan Management)的引入,能使 SQL 语句获得更加稳定的性能,官方不再推荐使用存储纲要。
DBMS_XPLAN 中显示的纲要数据对于我们来说具有相当重要的作用:
1、 它可以在不对语句做 OPTIMIZER_TRACE 的情况下,让我们了解优化器生成该执行计划的基本环境;
2、 利用纲要数据,我们可以在其他环境中重现一条语句的执行计划,以帮助我们做问题分析(Troubleshooting)和语句调优;
提示:纲要数据是由一组提示构成,在 11g 中,Oracle 提供了一个视图 V$SQL_HINT,可用于查询各个版本可用的提示。其中,字段 VERSION_OUTLINE 表示在某个版本中是否可用于计划纲要。
绑定变量信息
对于使用绑定变量,并且在解析计划时启用了绑定变量窥视特性的语句,在使用 DBMS_XPLAN 显示执行计划时,选择’ADVANCED’预定义格式作为参数或者加入’PEEKED_BINDS’控制字符串,可以在输出中看到以下内容:

其中,数字 1 为关联的操作 ID,:A 为绑定变量名(括号中中为变量数据类型,对于字符类型, 还有其字符集的 ID 号),最后为解析计划时,该变量所窥视到的数值。
绑定变量(Bind Variable)是 PLSQL 的一个重要特性。我们在描述 SQL 的处理过程中提到:SQL 被提交到 Oracle 后,会被哈希化,检查该语句是否已经存在内存中,以决定是否进行硬解析。而语句的细微差别(如大小写、注释、空格等)都会导致产生不同的哈希值,引起硬解析。而硬解析是一个相当消耗 CPU 的过程。通常,在应用中,同一条语句在不同的会话中可能会使用不同的数值作为参数。例如,一个系统登录模块,不同的用户登录时,会输入不同的用户名、密码作为参数,引发系统执行查询用户信息的语句。这样,任何一个用户都会导致这条语句得到一个不同的哈希值,从而 导致对其进行硬解析。
而绑定变量使 Oracle 避免了此类重复的硬解析。使用绑定变量的语句进行解析时,变量并不会代入具体数据,而是以:VARIABLE 的形式出现在语句中,在语句执行时,再将变量代入。
绑定变量的引入,可以帮助系统减少硬解析。但是,我们之前提到,CBO 是对数据敏感的优化器,在使用绑定变量对语句进行执行计划选择时,如果不考虑实际数据的分别性,可能会导致不能获取到最优的执行计划。例如,某张表上有一个字段 COL1,COL1 上建有索引,但其数据分别非常不均衡:其 99%数值为 A,%1 的数值为其它,如 B、C…在对该表以字段 COL1 作出条件查询时,如果查询数值为 A 的数据记录,则使用全表扫描比使用索引访问效率更高(全部扫描是多数据块读, 一次读入多个数据块;索引扫描一次读入单个数据块,并且需要访问索引和表两个对象);在查询其他数据时,使用索引访问会使语句的性能更好。如果在解析语句时,没有考虑实际的参数值,就可能会导致优化器选择一个错误的执行计划。
为了解决这个问题,在 Oracle 9i 中引入了绑定变量窥视(Bind Variable Peeking)特性。即在解析含有绑定变量的语句时,会“窥视”其具体数值以获取最优的执行计划。
不过,这一特性并不完善。以上述例子为例,如果解析语句时,窥视到的数值为 A,相应执行计划则为全表扫描。但如果该语句的其他执行的参数为非 A 数值,那么该执行计划则会导致这些执行出现性能问题。事实上,在 9i 和 10g 的系统,绑定变量这一缺陷导致性能问题屡见不鲜,而我们的解决手段通常是禁用绑定变量窥视特性(参数_optim_peek_user_binds 控制);使用存储概要(Stored Outline)、SQL 配置文件(SQL Profile)或提示等方法强制改变执行计划。在 11g 中,自适应游标共享(Adatpive Cursor Sharing)特性可以解决这一问题:它会比较绑定变量不同数值的执行计划的效率,相应的选择最优的执行计划。
分布式查询语句信息
分布式查询中,会涉及到对远程数据库上对象的查询。该部分信息则是将执行计划中涉及到远程对象查询的语句显示出来,语句是与执行计划中的操作相关联的。

注释(Note)
注释部分显示了在输出执行计划时所探测到的问题以及相关建议。例如,以下注释内容告诉我 们,该执行计划使用了 RBO 作为优化器,建议我们使用 CBO。





