Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >隐式数据类型转换案例一则

隐式数据类型转换案例一则

作者头像
老虎刘
发布于 2022-06-22 09:32:51
发布于 2022-06-22 09:32:51
4790
举报

OLTP系统中,要求对频繁执行的SQL使用绑定变量(唯一值少的字段,如type、status等,数据分布不均是常见情况,这种字段不建议使用绑定变量)。

在使用绑定变量时,有时开发人员对使用的字段类型不是很清楚,比如银行账号、电话号码、全数字型的序列号等,可以定义成number类型,也可以定义成varchar2类型。如果字段类型与绑定变量使用的数据类型不匹配,就会发生隐式类型转换。

常见的有害隐式类型转换发生在下面情况:varchar2_col = :number_variable

即varchar2类型的字段,使用的绑定变量类型是number类型,这将造成字段上的索引不能使用,如果是频繁执行的SQL,将会给系统带来严重的性能问题。

下面是一个比较让人迷惑的案例:

在对某客户一个重要系统进行优化时,在AWR的TOP SQL中遇到了这个SQL:

SQL代码非常简单:

SELECT NVL(MAX(DCC_PROC_ID),0)

FROM P_SERV A

WHERE ACC_NBR = :B2 AND SERV_ID <> :B1;

其中ACC_NBR(varchar2类型)和SERV_ID都是选择性很好的字段,两个字段上都有索引,因为SERV_ID是不等于条件,不能使用索引,那么这个SQL正常情况应该是使用ACC_NBR字段上的索引才是最佳路径。而且平均执行时间不应该超过1毫秒,实际显示平均执行时间达到了540毫秒,肯定有问题。

通过sqlhc工具收集了该SQL相关信息,发现SQL的执行计划有3个:

其中1最好,2和3都与1差了几百倍的性能。而根据常理,只有执行计划1才是比较正常的性能表现。

再看SQL执行情况,1和2两个计划同时存在,效率差别非常明显:

再来分别看3个执行计划的具体内容:

执行计划1,plan_hash_value=1228755719,使用了ACC_NBR字段上的索引,没有问题。

执行计划2,plan_hash_value=164228054,使用全表扫描的执行计划,在执行计划显示的最后部分,Predicate Information里,有TO_NUMBER(“ACC_NBR”)=:B2 字样,再结合上面部分的Peeked Binds信息,ACC_NBR字段使用的绑定变量是NUMBER类型,由此可以判断,这是因为绑定变量使用的数据类型与字段本身的类型不匹配,优化器自动对字段做了隐式类型转换,相当于在字段上使用了TO_NUMBER函数,这种情况就不能使用ACC_NBR字段上的索引:

再来看第3个执行计划,plan_hash_value=1669185283,这个执行计划因为是历史执行计划,看不到Predicate Information信息(只有sql执行计划存在于V$SQL_PLAN视图时,才会有Predicate Information信息,DBA_HIST_SQL_PLAN不保存这个信息),但是绑定变量使用的数据类型能够看到,是NUMBER类型。这种情况下,优化器还是因为隐式类型转换不能使用ACC_NBR字段上的索引,转而使用两个索引全扫描再做index join的执行计划,效率更差。

经过开发人员对代码的核对,发现这段SQL在两个不同的代码段中被调用,一段代码使用了正确的绑定变量类型(varchar2),而另一段则使用了number类型的绑定变量,这就造成了同一个sql_id, 同时存在多个不同执行计划的情况。这种情况应该属于应用代码不规范。

研发人员将使用number类型的绑定变量更换成varchar2类型后,SQL就都使用执行计划1了,执行效率大幅提高,CPU使用率也下降很多。

有的DBA在遇到这种多个执行计划同时存在的情况(这个情况比较特殊),可能会考虑使用SQL profile来固定执行计划,但是固定的执行计划只对正确使用绑定变量类型的SQL生效,对于不正确绑定变量类型,SQL profile也不起作用。

总结:

研发人员在使用绑定变量时,应该密切关注表字段定义的数据类型,尤其是当电话号码、账号信息等全数字的字段定义成varchar2时,千万不要使用number类型的绑定变量,否则会严重消耗系统资源,SQL本身性能也会非常差。

另一种情况是number数据类型的字段,在绑定变量是varchar2时,也会发生隐式类型转换。但是,这个隐式类型转换是发生在绑定变量上,因此不会对执行计划有影响,是无害的。

如何检查和发现系统中存在的隐式类型转换? 这里简单列出最常见的一种检查方法:

select sql_id,object_owner,operation,options,object_name,

filter_predicates,projection

from v$sql_plan where filter_predicates like 'TO_NUMBER%'

此外还有一些其他的隐式类型转换,如date类型的字段,使用了timestamp的绑定变量等,也需要注意。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
第一篇 热身--隐式类型转换还是其他?
刘老师,我这个SQL不能使用索引,你帮我确认一下,是不是遇到了“隐式类型转换”?然后发了一个执行计划的最后部分给我看:
老虎刘
2022/06/22
1970
一次有意思的错选执行计划问题定位(涉及SYS_OP_C2)
1. 11g的库,话说有一个应用程序新上线,应用中使用了绑定变量的方式执行一条简单的SQL,例如select a from b where c = :x,c列是该表复合主键的前导列,表定义是varchar2类型,从spotlight监控看这条SQL的执行计划是全表扫描,一次执行要1个小时,这张表是运行很久的引用分区表,数据量是亿级,测试的时候正常,但很显然测试的数据量可能和生产非常不一致,导致没察觉。
bisal
2019/01/29
6760
一个SQL性能问题的优化探索(一)(r11笔记第33天)
今天同事问我一个问题,看起来比较常规,但是仔细分析了一圈,发现实在是有些晕,我隐隐感觉这是一个bug,但是有感觉问题还有很多需要确认和理解的细节。 同事说有个10gR2的数据库SQL语句有性能
jeanron100
2018/03/21
7740
一个SQL性能问题的优化探索(一)(r11笔记第33天)
78-生产系统不改代码解决SQL性能问题的几种方法
数据库性能很大一部分跟SQL写法有关, 有些SQL是必须改代码才能优化的, 如果不能改代码, 需要删历史记录,回收空间,让表始终保持相对较小,才能消耗较少的资源,得到能够接受的响应时间.如前公众号文章所述: 必须通过改写SQL才能提升性能的一些情况 (列举了10个需要改写的SQL).
老虎刘
2022/06/22
4830
78-生产系统不改代码解决SQL性能问题的几种方法
【DB笔试面试586】在Oracle中,什么是自适应游标共享(3)?
从如下查询结果可以看到目标SQL对应的列VERSION_COUNT的值从之前的5变为了现在的6,列EXECUTIONS的值为7,说明Oracle在第7次执行目标SQL时依然用的是硬解析。从查询结果可以看到,Oracle此时新生成了一个CHILD_NUMBER为5的Child Cursor,并且把存储相同执行计划的CHILD_NUMBER为4的原有Child Cursor标记为非共享。
AiDBA宝典
2019/09/29
3940
为什么预估执行计划与真实执行计划会有差异?
一 问题概要 对同一个 SQL 语句的 ExplainPlan 里显示的预估执行计划与通过 V$SQL_PLAN 视图获取的 Runtime Plan 真实执行计划,偶尔会发现两边有不一致的情况,为什么呢?为什么预估执行计划会不准确?怎样才能避免这种情况的发生? 二 问题解答 这是执行计划相关中会被经常问道的问题,也是困扰自己很长时间的问题。希望通过下面的分析能解释一部分原因。 对同一个 SQL 语句的 ExplainPlan 里显示的预估执行计划与通过 V$SQL_PLAN 视图获取的真实执行计划不
数据和云
2018/04/17
8850
为什么预估执行计划与真实执行计划会有差异?
70-根因分析-oracle数据库突发性能问题,谁来背这个锅
数据库突发性能问题,有时可能通过重启应用、重新收集统计信息、重启数据库等方法得到临时解决,但是,如何把故障根本原因找到,避免故障再次发生,是问题得到完美闭环的一个关键步骤(当然,能够快速恢复业务也是非常关键的一环)。这也是为什么很多对业务稳定性要求非常高的行业(比如金融、通信、铁路、航空等)的数据库系统,购买oracle 售后高服(ACS)中的顶级服务SSC服务的一个主要原因。
老虎刘
2022/06/22
9400
70-根因分析-oracle数据库突发性能问题,谁来背这个锅
【DB笔试面试586】在Oracle中,什么是自适应游标共享(2)?
另外,在目标列有Frequency类型直方图的前提条件下,如果对目标列施加等值查询条件,且该查询条件的输入值等于该列的某个实际值时,则该谓词条件的可选择率的计算公式为如下所示:
AiDBA宝典
2019/09/29
5750
67-oracle数据库,有索引,但是没有被使用的N种情况,以及应对方法(上篇)
如果说性能优化是数据库技术中的明珠,那么索引无疑是其中最耀眼的一颗,特别是OLTP业务数据库。掌握了索引技术,基本上性能就不会有太大的问题。
老虎刘
2022/06/22
1.1K0
读书笔记-《基于Oracle的SQL优化》-第二章-1
1、目标SQL的正文、SQL ID和其执行计划所对应的的PLAN HASH VALUE。
bisal
2019/01/29
9820
殊途同归:如何获得一个SQL的真实执行计划
崔华,网名 dbsnake Oracle ACE Director,ACOUG 核心专家 如何查看一个sql的真实执行计划呢?用dbms_xplan.display_cursor(‘hash_value’,‘child_number’, 'advanced')是其中的一种很重要的方法。 我负责的一个库,在移植了大量数据后,跑最后一个运维作业的时候这个运维作业始终阻塞在这样的一个sql上: update saldat setsdaprs ='C',sdatno = :4 where
数据和云
2018/03/06
1K0
殊途同归:如何获得一个SQL的真实执行计划
Oracle 执行计划查看方法汇总及优劣比较
执行计划是一条 SQL 语句在 Oracle 数据库中的执行过程或访问路径的描述。如下图所示,是一个比较完整的执行计划示意图。
JiekeXu之路
2022/12/07
1.6K0
Oracle 执行计划查看方法汇总及优劣比较
【DB笔试面试598】在Oracle中,如何得到真实的执行计划?
在Oracle数据库中判断得到的执行计划是否准确,就是看目标SQL是否被真正执行过,真正执行过的SQL所对应的执行计划就是准确的,反之则有可能不准,因此,通过10046事件及如下的几种方式得到的执行计划是最准确的,而从其它方式获取到的执行计划都有可能不准确。
AiDBA宝典
2019/09/29
7900
【DB笔试面试586】在Oracle中,什么是自适应游标共享(1)?
绑定变量窥探的副作用就在于,使用了绑定变量的目标SQL只会沿用之前硬解析时所产生的解析树和执行计划,即使这种沿用完全不适合于当前的情形。在Oracle 10g及其后续的版本中,Oracle会自动收集直方图统计信息,这意味着与之前的版本相比,在Oracle 10g及其后续的版本中Oracle有更大的概率会知道目标列实际数据的分布情况,也就是说绑定变量窥探的副作用将会更加明显。当Oracle执行绑定变量窥探操作时绑定变量所对应的输入值是否具有代表性就至关重要了(这里“代表性”是指该输入值所对应的执行计划和该SQL在大多数情况下的执行计划相同),因为这会直接决定此目标SQL在硬解析时所选择的执行计划,进而决定后续以软解析/软软解析重复执行时所沿用的执行计划。
AiDBA宝典
2019/09/29
7590
案例分析:倾斜值传入导致 SQL 资源消耗升高
作者 | 邓秋爽:云和恩墨技术工程师,有超过七年超大型数据库专业服务经验,擅长 Oracle 数据库优化、SQL 优化和 Troubleshooting。
数据和云
2018/07/27
4850
案例分析:倾斜值传入导致 SQL 资源消耗升高
视图 v$sql,v$sqlarea,$sqltext,v$sqltext_with_newlines 的差异
      视图v$sql,v$sqlarea,v$sqltext,v$sqltext_with_newlines 是几个经常容易混淆的视图,主要是提供library cache中当前缓存的sql语句的信息。这几个视图都可以提供当前有关sql语句的具体信息,但稍有差异。本文主要描述其差异并给出实例。
Leshami
2018/08/14
1.2K0
按图索骥:SQL中数据倾斜问题的处理思路与方法
数据倾斜即表中某个字段的值分布不均匀,比如有100万条记录,其中字段A中有90万都是相同的值。这种情况下,字段A作为过滤条件时,可能会引起一些性能问题。 本文通过示例分享部分场景的处理方法 未使用绑定变量 使用绑定变量 几种特殊场景 1 测试环境说明 数据库版本:ORACLE 11.2.0.4 新建测试表tb_test: create tablescott.tb_test as select * from dba_objects; 创建索引: create indexscott.idx_tb_test_01
企鹅号小编
2018/01/23
1.1K0
按图索骥:SQL中数据倾斜问题的处理思路与方法
dbms_xplan之display函数的使用
DBMS_XPLAN包包括一系列函数,主要是用于显示SQL语句的执行计划,且不同的情形下使用不同的函数来显示,如预估的执行计划则使用 display函数,而实际的执行计划则是用display_cursor函数,对于awr中的执行计划,则是用display_awr函数,而SQL tuning集合中的执行计划 则由display_sqlset来完成。本文主要描述DBMS_XPLAN包中display函数的使用,尽管可以通过SQL语句来查询缺省表plan_table来获得执行计划, 事实上,使用display函数更便捷,且display函数提供了多种不同的显示格式。         有关执行计划中各字段模块的描述请参考: 执行计划中各字段各模块描述         有关由SQL语句来获取执行计划请参考:     使用 EXPLAIN PLAN 获取SQL语句执行计划         有关使用autotrace来获取执行计划请参考:启用 AUTOTRACE 功能         有关display_cursor函数的使用请参考:     dbms_xplan之display_cursor函数的使用 一、DBMS_XPLAN包中的函数
Leshami
2018/08/14
1.4K0
从Java的类型转换看MySQL和Oracle中的隐式转换(二)(r6笔记第68天)
说起数据类型转换,在开发中如此,在数据库中也是如此,之前简单对比过MySQL和Oracle的数据类型转换情况,可以参见MySQL和Oracle中的隐式转换 http://blog.itpub.net/23718752/viewspace-1787973/ 不过当时写完之后,有个读者随口问了一句为什么,为什么呢?似乎自己还是一知半解,说是规则,无规矩不成方圆,倒也无可非议,不过我觉得还是要再看看,看看还能有哪些收获,接下来的内容我就不能保证正确性了,希望大家明辨,也希望提出意见,毕竟就是希望把问题搞明白而已。
jeanron100
2018/03/16
1.1K0
Oracle之SQL优化专题02-稳固SQL执行计划的方法
糟糕的SQL执行,执行计划走全表扫描(这里实验直接利用使用hint强制不走索引来模拟这种情况):
Alfred Zhao
2019/05/24
8510
推荐阅读
相关推荐
第一篇 热身--隐式类型转换还是其他?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档