在Oracle数据库的性能调优过程中,获取准确的执行计划是定位SQL性能瓶颈的关键前提。许多开发人员习惯于使用SET AUTOTRACE或EXPLAIN PLAN命令来查看执行计划,然而这些传统方法只能展示预估的执行路径,一旦统计信息发生变化或存在绑定变量窥探,预估计划就会与实际执行情况产生严重偏差。为了获取最真实的执行路径,Oracle官方推荐使用DBMS_XPLAN工具包,它不仅能展示缓存中的执行计划,还能直接查询共享池中游标的真实运行时数据。

为什么必须使用DBMS_XPLAN查看执行计划?
传统的EXPLAIN PLAN命令将SQL语句的执行计划写入PLAN_TABLE表中,这个过程只进行硬解析,并不实际执行该SQL语句。这就意味着,如果查询中使用了绑定变量,EXPLAIN PLAN无法进行绑定变量窥探,它只能基于默认的猜测来生成计划。此外,由于统计信息的动态变化,预估的行数和成本可能与实际情况大相径庭,导致调优人员被错误的执行计划误导。
DBMS_XPLAN工具包则提供了更为强大和灵活的查询接口。它可以直接从库缓存中提取刚刚执行过的SQL语句的真实游标信息,不仅包含预估的行数和成本,还能通过特定参数获取实际执行的行数、逻辑读、物理读等运行时统计信息。这种从预估到实际的跨越,使得DBMS_XPLAN成为Oracle数据库性能诊断的核心利器,能够帮助开发者彻底避开预估计划带来的误导。
使用DISPLAY函数查看缓存执行计划
当我们在会话中执行了EXPLAIN PLAN FOR命令后,执行计划会被存储在当前会话的PLAN_TABLE中。此时,可以使用DBMS_XPLAN.DISPLAY函数来格式化输出这些计划。这是最基础的查看方式,适用于不需要实际运行SQL的场景。该函数接收三个主要参数:表名、语句ID和格式化字符串。如果不指定表名,默认查询PLAN_TABLE表。
在格式化输出方面,FORMAT参数非常关键。常用的格式包括BASIC、TYPICAL、ALL等。BASIC只显示最基础的操作步骤,TYPICAL是默认值,会显示行数、成本和谓词信息,而ALL则会展示更为详细的列投影信息。通过合理配置FORMAT参数,我们可以快速获取所需的调优线索,避免被过多无用信息干扰。
-- 使用EXPLAIN PLAN生成执行计划 EXPLAIN PLAN FOR SELECT employee_id, last_name, salary FROM employees WHERE department_id = 80; -- 使用DBMS_XPLAN.DISPLAY查看计划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'ALL'));
上述代码展示了如何将一条查询的预估计划写入PLAN_TABLE,并通过DISPLAY函数以ALL格式输出。需要注意的是,这种方法依然存在预估计划的局限性,如果条件允许,应优先使用DISPLAY_CURSOR函数获取真实计划。
使用DISPLAY_CURSOR获取真实运行时执行计划
要获取SQL语句在数据库中真实执行的路径,DBMS_XPLAN.DISPLAY_CURSOR函数是最佳选择。它直接从共享池的库缓存中提取游标信息。使用该函数前,必须确保当前会话拥有查询V$SQL、V$SQL_PLAN等动态性能视图的权限。DISPLAY_CURSOR接收三个参数:SQL_ID、CHILD_NUMBER和FORMAT。如果不提供SQL_ID,函数默认返回当前会话刚刚执行的上一条SQL语句的执行计划。
获取SQL_ID的方法有很多,最常用的是通过查询V$SQL视图。一旦拿到了SQL_ID和对应的子游标编号,就可以将其传入DISPLAY_CURSOR函数中。这种方法最大的优势在于能够结合运行时统计信息,展示出每一步操作实际处理的行数,这对于判断统计信息是否准确、连接方式是否合理具有决定性的指导意义。
-- 查找目标SQL的SQL_ID SELECT sql_id, child_number, sql_text FROM v$sql WHERE sql_text LIKE '%SELECT employee_id, last_name%' AND sql_text NOT LIKE '%v$sql%'; -- 传入SQL_ID和CHILD_NUMBER查看真实执行计划 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id => 'your_sql_id_here', cursor_child_no => 0, format => 'ALL'));
通过上述查询,我们可以清晰地看到该SQL在硬解析阶段生成的真实执行路径。如果SQL执行了多次但生成了不同的子游标,通过指定不同的CHILD_NUMBER,还能对比不同游标执行计划的差异,从而深入分析绑定变量窥探带来的影响。
深入解析FORMAT参数与高级诊断信息
FORMAT参数是DBMS_XPLAN的精髓所在,它决定了输出信息的丰富程度。除了基础的TYPICAL和ALL之外,还有一组专门用于获取运行时统计信息的格式选项。其中最常用的是ALLSTATS LAST。当指定该格式时,DBMS_XPLAN会显示最后一次实际执行该SQL时的统计信息,包括A-Rows(实际处理的行数)、A-Time(实际执行时间)、Buffers(逻辑读次数)和Reads(物理读次数)。
对比E-Rows(预估行数)和A-Rows(实际行数)是SQL调优的核心步骤。如果两者差距巨大,说明统计信息陈旧或存在直方图缺失,导致优化器做出了错误的成本估算。此时,收集准确的统计信息或添加合适的提示就能解决问题。此外,通过PEEKED_BINDS格式,还能查看到硬解析时窥探到的绑定变量具体值,这对于理解为什么优化器选择了某个特定的执行计划至关重要。
-- 获取最后一次执行的详细运行时统计信息 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format => 'ALLSTATS LAST')); -- 获取谓词信息和窥探到的绑定变量值 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format => 'ALL +PEEKED_BINDS'));
在使用ALLSTATS LAST格式时,如果发现某些步骤的A-Rows为空,说明该SQL可能尚未在当前会话中执行,或者由于内存换页导致统计信息丢失。熟练掌握这些高级格式参数,能够帮助开发人员像剥洋葱一样,一层层揭开SQL执行过程中的黑盒,精准定位到消耗资源最多的具体操作步骤,从而制定出最有效的优化策略。
Oracle DBMS_XPLAN执行计划性能优化修改时间:2026-08-28 08:27:09