预备知识
如果执行过的SQL,想要知道执行过程中绑定的值,可以通过以下方法来处理(注意 只能取到编译时候的值, 如果SQl共享了,只能取到第一次执行绑定的值):
1.如果SQL还在 shared_pool里,可以通过 一下SQL来获取
select other_xml from v$sql_plan where sql_id='xxxx'
2. 如果SQL 已经不在 shared_pool里,还可以通过 以下SQL来获取
select other_xml from dba_hist_sql_plan where sql_id='xxxx'
3.如果都找不到了, 那就木有办法了
案例 找绑定的值
create table t1 (c1 varchar2(20));
begin
for i in 1..10000 loop
insert into t1 values (i);
end loop ;
end;
var b1 varchar2(10);
exec :b1:='1233211';
select * from t1 where c1=:b1;
select * from table (dbms_xplan.display_cursor(null, null, 'allstats +alias +outline'))
SQL_ID gjrwvap4h9b61, child number 0
-------------------------------------
select * from t1 where c1=:b1
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 6 (100)| |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 12 | 6 (0)| 00:00:01 |
取到SQLID gjrwvap4h9b61
select to_char(other_xml) from v$sql_plan where sql_id='gjrwvap4h9b61';
<other_xml>
<info type="db_version">10.2.0.1</info>
<info type="parse_schema"><![CDATA["SYS"]]></info>
<info type="dynamic_sampling">yes</info>
<info type="plan_hash">3617692013</info>
<peeked_binds> //编译时候绑定的值 在这一节
<bind nam=":B1" pos="1" dty="1" csi="873" frm="1" mxl="32">31323333323131</bind>
</peeked_binds>
<outline_data>
<hint><![CDATA[IGNORE_OPTIM_EMBEDDED_HINTS]]></hint>
<hint><![CDATA[OPTIMIZER_FEATURES_ENABLE('10.2.0.1')]]></hint>
<hint><![CDATA[ALL_ROWS]]></hint><hint><![CDATA[OUTLINE_LEAF(@"SEL$1")]]></hint>
<hint><![CDATA[FULL(@"SEL$1" "T1"@"SEL$1")]]></hint>
</outline_data>
</other_xml>
// 用内部转换一下 看一下实际的值
exec dbms_stats.convert_raw_value( hextoraw('31323333323131'), :b1);
SQL> print b1;
B1
--------------------------------
1233211
这个下边是实际的outline 和 上边 <outline_data> </outline_data> 的是一模一样的
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
FULL(@"SEL$1" "T1"@"SEL$1")
END_OUTLINE_DATA
*/
实际上如果在修改 :b1:的值 然后执行,xml内绑定的值 是不变的
执行过程中抓值 可以通过 GV$SQL_BIND_CAPTURE中来
案例 SQL调优的一般步骤
1. 看执行计划, 有没有走索引
2.看 a-row 和 e-row是否相差很大
3.能重新跑的 重新跑一下
4. 执行时间长,跑不完的收集 sql-t或者 sql-health
索引过滤一遍 还有很多数据, 然后经过一个条件 只有几条数据了,如果这个查询常用 是否考虑 用这个条件和 已经有的索引 组件一个联合索引