ITPub博客

首页 > 数据库 > Oracle > oracle执行计划------未走索引,隐式转换的坑

oracle执行计划------未走索引,隐式转换的坑

原创 Oracle 作者:e71hao 时间:2021-03-21 14:32:43 0 删除 编辑

一、问题

业务方一条sql语句很奇怪,执行时间0.4秒,数据量不大,两张表,每张表40万条数据,左连接,都有索引,where条件字段有索引。

看上面执行计划,是不是很完美。查询出来一条数据,谓词条件AGGREGATE_ORDER_NO = :1   也很完美,可以定位出来一条语句。

二、分析

      这个语句说简单其实很简单,2个表,左连接,每个表数据量40多万。执行计划也显示出完美情况来。但是在awr报表中这个语句平均执行时间0.4秒,按理来说,应该是0.01秒,或者0.00秒,忽略不计的呀。难道我这个执行计划有问题?不是真实的执行计划?

三、检验是否是真实执行计划

 

看真实的执行计划,就用如下语句:

 ALTER SESSION SET STATISTICS_LEVEL=ALL;

 execute sql 

 select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

用如上方法可以查看执行计划,因为使用了绑定变量,所以我设置一下

var  vno varchar2(80)

exec :vno :='sjdkfjlks'


select a.PAY_TYPE, a.STORE_ID, a.AGGREGATE_ORDER_NO, a.TOTAL_PAYABLE_AMOUNT, a.ACTUAL_PAY_AMOUNT, a.CURRENCY, a.REMARK, a.AGGREGATE_ORDER_STATE, a.BUSINESS_ORDER_STATE, a.CREATE_TIME, a.BUSINESS_LINE, a.COMMENT_ORDER_STATE, a.REFUND_ORDER_STATE, a.SHOW_URL as SHOP_LOGO, a.STORE_NAME, a.BUSINESS_CONTENT, p.OUT_PAY_ORDER_NO, p.PAY_STATE from xxx_ORDER a left join xxx_order p on(a.pay_order_no = p.pay_order_no) where a.DEL_STATE = 10 and a.AGGREGATE_ORDER_NO = to_char(:vno) order by a.id desc 

结果发现还是没有问题

四、分析到这里好像进入了死胡同,执行计划没有问题,索引也有,但是执行时间就是下不来,而且还提示这个语句占用cpu巨多。思索了好几天,困扰了我好几天。后来灵机一闪,是不是应该把awr的执行计划调出来呢?

用如下语句调用awr执行计划

select * from table(dbms_xplan.display_awr('3ypyandfvscts',null,null,'all'));

仔细看上面执行计划,发现了没有,居然没有走索引扫描,而是走了全表扫描。不是有索引吗?百思不得姐

五、看上面的分析,好像又陷入了死胡同,百思不得姐。为啥明明有索引,却不走索引呢?百度了一下,不走索引有哪些情况呢?

比较不匹配类型的数据类型

等于和范围索引不会被合并使用

WHERE子句中使用不等于条件

使用前导模糊查询

WHERE子句中使用函数

后来经过我和开发仔细对照,发现传给绑定变量的是数字,而不是字符串。所以,我做了如下实验发现,果然,如果是数字,会导致不走索引。

看到上面关键语句r((TO_NUMBER("A"."AGGREGATE_ORDER_NO")=:VNO,导致全表扫描。

六、结论出来了,改变也容易了。开发写错误,把是字符串类型写成数字类型。纠正过来就可以了,执行时间是0.00秒,问题解决。困扰我几天的问题解决了。百思不得姐

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30393770/viewspace-2764049/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-08-05

  • 博文量
    133
  • 访问量
    235553