共计 2296 个字符,预计需要花费 6 分钟才能阅读完成。
当一个 SQL 呈现性能问题时,能够应用 SQL_TRACE 或者 10046 事件来跟踪 SQL,通过生成的 trace 来理解 SQL 的执行过程。咱们在查看一条 SQL 的执行打算的时候,只能看到 CBO 最终通知咱们的执行打算后果,然而不晓得 CBO 是依据什么来做的。如果遇到了执行打算异样,能够借助 Oracle 10053 事件进行跟踪。10053 事件是 oracle 提供的用于跟踪 sql 语句成本计算的外部事件,它能记录 CBO 模式下 oracle 优化器如何计算 sql 老本,生成相应的执行打算。
通过 session 级别跟踪:
ALTER SESSION SET EVENTS=’10053 trace name context forever, level 1′;
或 ALTER SESSION SET EVENTS=’10053 trace name context forever, level 2′;
执行相干 sql
explain plan for select count(*) from obj$;
ALTER SESSION SET EVENTS ‘10053 trace name context off’;
对特定 session 启用跟踪:
通过调用 DBMS_SYSTEM. SET_EV 包实现
PROCEDURE SET_EV
Argument Name Type In/Out Default?
—————————— ———————– —— ——–
SI BINARY_INTEGER IN
SE BINARY_INTEGER IN
EV BINARY_INTEGER IN
LE BINARY_INTEGER IN
NM VARCHAR2 IN
查问 v$sessiowww.pizei.comn 视图获取过程信息
SQL> select sid,serial#,username from v$session where username is not null;
SID SERIAL# USERNAME
125 25 SYS
执行跟踪
exec dbms_system.SET_EV(125,25,10053,1,”);
完结跟踪
exec dbms_system.SET_EV(125,25,10053,0,”);
查问零碎对应 session trace 文件
select value from v$diag_info where name = ‘Default Trace File’;
通过开发人员确认该 sql 在测试库(LINUX+ 12.2.0.1 单机环境)执行只须要几秒即可(数据量相差不大)实现,其中 bs_loan_card_addition、bs_loan_card、bs_loan_contract_addition 三张表的数据量都在 200 万行左右。
获取到生产环境该 sql 执行打算如下:
测试环境该 sql 执行打算如下:
首先狐疑统计信息不精确导致 CBO 在页游拜访 BS_LOAN_CARD 表的时候抉择谬误,本应该抉择 BS_LOAN_CARD_I3 索引(因为 CUSTOMER_NO”=’1000193229’的选择性很好)而这也是开发设计这个索引的起因。但后果是抉择了 BS_LOAN_CARD_I0 索引(对应的是 BS_LOAN_CARD.LOAN_CARD_NO, 该列惟一的),而过滤条件基本没有这个列,他只是作为关联条件与 bs_loan_card_addition 表进行连贯。
因而首先查看统计信息,意外发现 BS_LOAN_CARD.LOAN_CARD_NO, 列上竟然存在一个 HYBIRD 类型的直方图,实践上来说该值的唯一性十分好,不应该收集直方图,因而间接删除了该列上的直方图,再次查看发现执行打算仍未扭转。
尝试应用 10053 对该 SQL 执行打算的产生过程进行跟踪,发现如下信息:
而且联合执行打算
这个执行打算简略了解来说就是首先对 BS_LOAN_CARD_ADDITION 进行全表扫描,而后在这个所得的后果集外面每一行的 LOAN_CARD_NO 列拿出来到 BS_LOAN_CARD 外面匹配,这就是第 6 部外面呈现了一个 "B"."LOAN_CARD_NO"=:B1 起因,而这个就是 oracle 改写后的后果。而从其抉择对 BS_LOAN_CARD_ADDITION 进行全表扫描就不可避免的导致了效率会很低。而且其后的 rows 估算为 2444K,这个是贴合理论的,所以之前的删除直方图不会有后果。而测试上的改写后果显著跟这个不一样,排除统计信息的影响,那么就开始狐疑 cbo 外部的算法抉择问题,再联合那个可疑 的“CBQT bypassed forquery block UPD$1 (#0): Disabled by parameter.”提醒,狐疑优化器参数在两个环境中有区别,
一:_optimizer_cost_based_transformation 设为 linear(默认值),其有如下值:
“exhaustive”, “iterative”,”linear”, “on”, “off”。
本例中该参数就是默认值,该参数可管制是否容许 CBO 进行改写
二:_optimizer_squ_bottomup 参数值为 true(默认值).
而生产环境中恰好相反为 false,所以生产的 trace 中会有 Disabled by parameter 字眼
_optimizer_squ_bottomup enables unnesting of subquery in a bottom-upmanner;
该参数默认为 true,即开启子查问自底向上的开展性能(也就是相似 unnest hint 的性能),unnest 称之为对子查问开展,顾名思义,就是不让子查问孤独地嵌套 (nest) 在外面。