sql子游标不共享造成的硬解析

昨天遇到一个数据库运行缓慢的问题,awr报告部分信息如下:

sql子游标不共享造成的硬解析

 

 

 sql子游标不共享造成的硬解析

 

 

 看到这里判断应该是硬解析太多造成的,直接登录数据库查看了一下当前等待事件,

sql子游标不共享造成的硬解析

大量cursor:pin S wait on X和library cache lock 等待,很明显在等待硬解析,查看当前的阻塞情况,阻塞都也是grfvv7n41241w语句造成的,

grfvv7n41241w是一个查询语句,很多业务操作中要用到。查看了执行计划版本,没有变化。为什么会这么多硬解析呢?sql子游标不能共享造成硬解析,

查看了一下v$sql_shared_cursor视图,该SQL的bind_equiv_failure 为Y,查看文档中bind_equiv_failure意思

BIND_EQUIV_FAILURE VARCHAR2(1) (Y|N) The bind value‘s selectivity does not match that used to

optimize the existing child cursor

绑定值的选择性与用于优化现有子游标的选择性不匹配,不太好理解。

查看sql的绑定变量

sql子游标不共享造成的硬解析

 

 查看对应表中字段的数据类型为NVARCHAR2,这样原因就明确了,绑定变量数据类型与字段类型不一致导致子游标不能共享。

怎么会类型不一致呢?查看了一下执行计划,其中有一些SYS_OP_C2C函数比较特别。

sql子游标不共享造成的硬解析

 

 

 应用的同事在网上找到了一篇博文,解释了这个问题,ORACLE中内部函数SYS_OP_C2C和隐式类型转换,并且给出了解决方案,应用是JDBC连接,

用博文中的第二种方案解决了。再次查询看到数据类型一致了。

sql子游标不共享造成的硬解析

 

 

 

有两个疑问, 对JAVA不太了解应该与应用程序有关。

1、绑定变量的数据类型不匹配为什么是BIND_EQUIV_FAILURE而不是SQL_TYPE_MISMATCH?

2、应用已上线运行半年多了,怎么会现在才出现这个问题呢?

 

sql子游标不共享造成的硬解析

上一篇:SqlServer 查询系统数据库列表、表和表字段等对象


下一篇:MySQL 学习记录 - 索引