一个执行计划解析的小问题分析

前几天,一个开发的同学让我帮忙做一个大查询,给了我一个数据列表,里面的ID有几万个,提供了一个SQL语句,看这情况还得我自己来解析生成相关的SQL了。
假设ID列表为:
T100
T200
T300
SQL语句为:
select peak_transaction_id,cash ,req_time  ,back_time  from peak_new.peak_detail where peak_transaction_id=?;
对我来说拼成动态SQL也是分分钟,但是这种方式不推荐,还是推荐使用数据的结果集方式来匹配。
所以我可以根据id拼接成insert语句,或者直接使用外部表来关联。表里只有一个字段id varchar2(30)
在运行语句之前我还是会照例来查看执行计划,如果太差我就提前想别的办法了。
执行计划着实让我大跌眼镜。一个简单的键值关联的语句,执行计划竟然如此的查,来看看瓶颈在哪里。

可以从谓词信息看出,里面做了数据类型的转换,根据ID这个字段值数据类型应该是varchar2,是不需要转换为number类型的。
但是通过执行计划看出,内部是做了数据类型的转换,最后这种关联方式的消耗竟然如此惊人。
我就感觉有些蹊跷,为什么会有这种差别,按理来说是不需要这种类型转换啊。
调用的SQL语句如下:
select TEST_transaction_id,cash ,req_time  ,back_time  from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
发现问题的症结在于tempdba.test不是我刚刚创建的临时表,而是指向了一个已经存在的表。这个表的结构如下:


所以这个问题就有点意思了,tempdba.test虽然和属主下的表test同名,但是字段完全不同,在生成执行计划的时候竟然还能成功,这个也让人着实怀疑优化器处理执行计划是不是也有很多不足之处。
我使用了正确的schema之后,重新生成执行计划,这一次得到的预估结果还是在接受范围之内。我完全可以在备库去跑这个查询实现目标。

那么问题来了,是不是执行计划对于字段的校验存在疏漏呢,我们来简单测试几个小例子。
发现在常见的表关联中还是能够校验出来的。

再来看看exists的方式是否也有问题。发现也是可以检测出来的。

所以再回头看这个问题,就会发现在最开始的语句中。
select TEST_transaction_id,cash ,req_time  ,back_time  from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
采用in的子查询的时候,对于子查询中的列可以和关联的表不同名,我们可以取别名来达到的兼容的目的,我想正是如此在执行计划中也会弱化了这方面的检查,严格来说,姑且算是一个bug吧。

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

转载于:http://blog.itpub.net/23718752/viewspace-2120633/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值