自相矛盾:Null is Not Null引发的成本误区
黄玮(Fuyuncat)
资深Oracle DBA,个人网,致力于数据库底层技术的研究,其作品获得广大同行的高度评价.
在SQL的世界里,总有一些情况是你意想不到的,以下这个案例可以让你理解这样一种情况。
这是一个开发者请求分析的一个SQL,原因是执行计划很让人费解。首先通过Explain执行一次SQL,获取执行计划:
在以下的执行计划中,可以看到第三步骤的执行计划成本为100,而最终的成本却是0,这是让人最为费解之处:
那么仔细观察一下过滤谓词,可以看到一个奇妙之处,第二步骤处有一个过滤谓词信息,这是优化器自动添加上去的,其判定为NULL IS NOT NULL,这显然是一个恒假的条件.
根据这个条件,Oracle无需执行所有SQL,直接返回,这也就是无论执行计划树的成本是多少,最终过滤的成本总是0,SQL无需真正执行。
那么为什么会有这样一个始终为False的条件呢?从SQL中可以看出端倪。
在SQL代码中存在如下条件:
6 AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')='DELETED'
7 AND NVL(MVMT.EVENT_CURRENT_CONTRA_IND,'0')= 'ROLLBACK'
按照这个条件,'DELETED'='ROLLBACK',这显然不可能,所以出现了恒假的条件,最终确认是程序员的疏忽导致的错误编码。
在程序的世界里,什么事情都可能发生,所以在开发过程中进行必要的SQL审核,不可缺少。
如何加入"云和恩墨大讲堂"微信群
搜索 盖国强(Eygle)微信号:eyygle,或者扫描下面二维码,备注:云和恩墨大讲堂,即可入群。每周与千人共享免费技术分享,与讲师在线讨论。
2016DTCC, 2016数据库大会PPT;
DBALife,"DBA的一天"精品海报大图;
12cArch,“Oracle 12c体系结构”精品海报;
DBA01,《Oracle DBA手记》第一本下载;
YunHe,“云和恩墨大讲堂”案例文档下载;