前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入剖析:not exists对外层查询的影响

深入剖析:not exists对外层查询的影响

作者头像
数据和云
发布2018-03-06 16:29:37
6890
发布2018-03-06 16:29:37
举报
文章被收录于专栏:数据和云数据和云

何剑敏

Oracle ACS华南区售后团队,首席技术工程师。供职于Oracle ACS华南区售后团队,首席技术工程师。多年从事第一线的数据库运维工作,有丰富项目经验、维护经验和调优经验,专注于数据库的整体运维。

编辑手记:运维中会面临各种各样的问题,有时候我们不能找到问题的根源就是因为在我们心里,有一个想当然的答案,比如认定了600就是bug,1555就是undo设置不合理,这些想当然的答案在很大程度上阻碍了我们的分析。我们通过今天的分享一起学习如何拨开云雾,发现问题的真相。

同事在12c中跑的buffer get很高,但是在10g中跑的buffer很低。怀疑是不是12c的优化器有问题。接下来我们一起来验证。

本例中的10g的环境和12c的环境,数据量大致一样,只是有很少部分的不同,但是就是这个很少部分不同,造成了not exists中的子查询返回不同的值,进而对外层查询产生不同的影响。我们来用如下的代码模拟一下。

初始化数据:

--10g

--12c

我们看到,12c的数据和10g只是有很少的差别,t1表12c和10g都一样,t2表在12c只是少了一行数据。

--10g

--12c

我们将要执行的sql语句是:

我们先来看执行情况的差距,10g的bufferget小,12c多

--10g

查看执行计划

--12c

看执行计划

可以看到第23,24行,在10g中运行时,buffers是0,而在12c中,即78,79行,buffer是2083+6496。也就是说在本次测试中,10g,外层查询不进行t1和t2的扫描,直接返回结果了,而12c,外层查询还要进行t1表和t2表层扫描才返回结果

那究竟是不是版本的差异呢?

这其实不是10g和12c的差别,而是not exists的返回数据对外层的影响。子查询要返回0行记录,才满足not exist的条件,从而返回外层查询结果。在10g中,子查询返回了一行记录

不满足not exists(即0行才满足),所以,也就不用在外层继续查询了。直接返回记录0行。

在12c中,子查询返回0行记录,满足not exist的条件,所以还需要在外层查询中继续查询。

正是这一行记录的差异,导致了not exists对外层查询的影响。进而导致整个sql的buffer get的差异。

反证这个结果,我只要在12c中,运行子查询结果返回大于0行的,不满足not exists,也应该不会去外层查询了。见下:

看执行计划

可以看到第38,39行的buffer为0.

最终我们验证了,其实并不是版本的差异。所以任何时候,一定要耐心细致地分析问题,拨开云雾,找到故障的根源。

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

本文分享自 数据和云 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档