一、问题
业务方一条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/ ,如需转载,请注明出处,否则将追究法律责任。