java绑定变量的值_一个执行计划异常变更的案例 – 外传之查看绑定变量值的几种方法...

这篇外传之前有这么几篇文章:

《一个执行计划异常变更的案例 - 前传》

《一个执行计划异常变更的案例 - 外传之绑定变量窥探》

上一篇文章介绍了绑定变量以及11g之前绑定变量窥探的影响,这篇文章会介绍几种查看绑定变量值的方法。

上篇文章我们说了,绑定变量实际是一些占位符,可以让仅查询条件不同的SQL语句可以重用解析树和执行计划,避免硬解析。绑定变量窥探则是第一次执行SQL硬解析时,会窥探使用的绑定变量值,根据该值的分布特征,选择更合适的执行计划,副作用就是如果绑定变量列值分布不均匀,由于只有第一次硬解析才会窥探,所以可能接下来的SQL执行会选择错误的执行计划。

有时可能我们需要查看某条SQL使用了什么绑定变量值,导致执行计划未用我们认为最佳的一种。

方法一:10046

使用level=4的10046事件,查看生成的trace文件,

776c2141315360384b3d7b1def8f6364.png

可以看出绑定变量值是’Z’。

68bfdf3476ef0c6acd06a67b23f67ce1.gif

方法二:v$sql_bind_capture

首先找出SQL对应的sql_id,

c72d9caf7ae391b9ff9a27bc49d4af4d.png

从v$sql_bind_capture可以看出两个绑定变量占位符以及对应的值,

1f148839b28d2c56a7b2b06c9e66887c.png

这里有一点值得注意的就是,DATATYPE_STRING列的描述是“绑定变量数据类型的文本表示”,开始我认为就是绑定变量字段的数据类型,但实际看来不是,DATATYPE_STRING列只是来告诉你绑定变量列是字符型,还是数值型。

6bdff28267814f7b504a0738854d7b41.png

我们此时换一下绑定变量值,发现vsql_bind_capture信息未变,dbsnake的书中曾说过当SQL执行硬解析时绑定变量值被捕获,并可从视图v$sql_bind_capture中查询。

f2728c7caa666d26791b55d1c55250e4.png

对于执行软解析/软软解析的SQL,默认情况下间隔15分钟才能被捕获,为了避免频繁捕获绑定变量值带来的系统性能开销,而且从常理上认为,既然使用了绑定变量,最佳方式就是值分布均匀,只需要SQL执行第一次硬解析时窥探一下,后续执行的SQL执行计划应该比较稳定,因此只要能比较实时地查看第一次绑定变量值即可。间隔15分钟受隐藏参数_cursor_bind_capture_interval控制,默认值是900s,15分钟。

96e3feedb73de6c3a848d0232779919a.png

我们尝试将捕获绑定变量的间隔时间调短,该参数不支持session级别修改,

26a8816768e6fb42b5b0bbe962d3eb42.png

执行alter system级别操作,

5b3b23ad2f5cdb2c2578b3147d2daab0.png

等大约一分钟,此时可以从v$sql_bind_capture查询刚使用的绑定变量值,

68bfdf3476ef0c6acd06a67b23f67ce1.gif

方法三:AWR信息

(1) DBA_HIST_SQLBIND视图包含了v$sql_bind_capture的快照。

68bfdf3476ef0c6acd06a67b23f67ce1.gif

因此对应的SQL语句,和v$sql_bind_capture很像,

select name,datatype_string,value_string,datatype from DBA_HIST_SQLBIND

where sql_id='...'

(2) 另一个视图,DBA_HIST_SQLSTAT记录了SQL统计信息的历史信息,他是基于一些标准,捕获来自于V$SQL的统计信息。可以使用如下SQL,

select snap_id, dbms_sqltune.extract_bind(bind_data,1).value_string bind1, dbms_sqltune.extract_bind(bind_data,2).value_string bind2, dbms_sqltune.extract_bind(bind_data,3).value_string bind3 from dba_hist_sqlstat where sql_id = '...'order by snap_id;

其中dbms_sqltune.extract_bind(bind_data,1).value_string取决于SQL中绑定变量的数量。

第一次执行这两条SQL时,并未有任何结果返回,我猜测可能是这条SQL不符合AWR采集的标准。从MOS中查到这篇文章:《How to Control the Set of Top SQLs Captured During AWR Snapshot Generation (文档 ID 554831.1)》,用其中的方法修改下AWR采集topnsql参数,

6970a97bca01b0b48846bcb006078f99.png

默认值是

d67ed9a9679d4c00da203000ddd36f1c.png

含义是,

ccd54fd82d5ea5ce6645d2d69b917982.png

此时重新执行SQL,默认AWR会一小时采集一次,此时可以手工采集AWR快照,

d230b9210b5efca5422246ccb53d0c22.png

此时再次查询DBA_HIST_SQLBIND,

2d3b8cc8b61a2ed4ab21225b6ff4c992.png

再次查询DBA_HIST_SQLSTAT,

68bfdf3476ef0c6acd06a67b23f67ce1.gif

方法四:EM?

本以为任何可以使用SQL执行,都可以从EM中找到相应的界面,但未找出绑定变量值可以检索的地方,若是有朋友知道,可以告诉我们。

68bfdf3476ef0c6acd06a67b23f67ce1.gif

68bfdf3476ef0c6acd06a67b23f67ce1.gif

总结:

绑定变量值可以使用很多方法获取,这里只是列举了三种最常见的方法,我从网上看到有朋友还有用wrh_stat、v$sql等视图查询的例子,没有深究,我觉得碰见问题时,可以快速使用一些常用的方法解决问题就可以了,当然时间充裕的话,建议还是多从原理层了解一些,做到触类旁通则最好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值