在实践中ORACLE数据库的SQL中存在隐式转换(即执行平均处理行数:查询出的行数,更新的行数)会引发性能问题。
常见的两类发生隐式转换引的情形:
1.字符转换为数值
2.char、varchar 转换为 Nchar、Nvarchar。
当赋值与字段数据类型不一致时,就会发生隐式转换。当发生隐式转换时,可能会导致对应字段上的索引无法使用(即索引失效),进而产生性能问题。开发过程中要避免隐式转换,需要的话,可以使用显示转换。
通过检索DB当前缓存的执行计划中的谓词信息可以发现隐式转换。
常见的隐式转换,通常有下面两种:
1.字符类型转换为数值类型,谓词特征:TO_NUMBER()。
2.varchar2类型转换为nvarchar类型,谓词特征:SYS_OP_C2C()。
隐式转换不仅发生在where条件中,还会发生在表连接中,常常导致无法使用索引,严重影响SQL执行效率。
问题排查:
对于发生隐式转换的SQL,可通过查看其执行计划中的谓词信息发现隐式转换发生的具体位置,特征关键字为TO_NUMBER、SYS_OP_C2C,对应执行步骤通常为全表扫描,即使有索引也将无法使用。
查看当前系统缓存中的执行计划的语句,入参为sql_id:
select * from table(dbms_xplan.display_cursor(sql_id => '&sql_id',cursor_child_no => null));
如果上面SQL查询结果为空,说明SQL已经被清除出缓存了。
这种情况下,可使用explain plan查看执行计划:
1.生成执行计划,绑定变量可不用赋实际值
explain plan for <SQL文本>
2.查看执行计划
select * from table(dbms_xplan.display);
整改建议:
修改赋值的数据类型,保持与字段类型一致。
表连接的话,修改关联字段类型,保持关联字段类型一致。
更多内容请关注公众号“测试小号等闲之辈”~