暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

子查询反嵌套(Subquery Unnesting)

原创 由迪 2020-08-19
2089

在对存在嵌套子查询的复杂语句进行优化时,查询转换器会尝试将子查询展开,使得其中的表 能与主查询中的表进行关联(Join),从而获得更优的执行计划。部分子查询反嵌套属于启发式转换,部分属于基于代价的转换,下面会做特别说明。

提示:提示 UNNEST/NO_UNNEST 可以控制是否进行反嵌套。在 11G 中,也可以由优化器参数
_optimizer_unnest_all_subqueries 控制。

IN/EXISTS 转换为 SEMI JOIN
转换器将 IN 或 EXISTS 子句中的子查询展开(反嵌套),使得优化器能选择半关联(SEMI-JOIN) 操作。这种转换属于启发式转换。
示例
image.png
image.png
在上例中,EXISTS 子句中的子查询被展开,其中对象与主查询中对象直接进行半关联操作。
NOT IN/NOT EXISTS 转换为 ANTI JOIN
转换器将 NOT IN 或 NOT EXISTS 子句中的子查询展开(反嵌套),使得优化器能选择反关联
(ANTI-JOIN)操作。这种转换属于基于代价的转换。
示例:
image.png
image.png

在上例中,NOT EXISTS 子句中的子查询被展开,其中对象与主查询中对象直接进行反关联操作。
NOT IN/NOT EXISTS 转换为 Null-Aware ANTI JOIN(11g)
转换器将 NOT IN/NOT EXISTS 子句中的子查询展开(反嵌套),使得优化器能选择对空值敏感的反关联(Null-Aware ANTI-JOIN)操作。这种转换属于启发式转换。
在下例当中,字段 T_OBJECTS.OBJECT_NAME 允许为空(不存在非空约束)。
提示:对空值敏感的反关联操作能在关联数据时关注到空值的存在,从而避免使用代价高昂操作
(例如笛卡尔乘积关联)来获取逻辑结果。
示例:
image.png
image.png
在上例中,NOT IN 子句中的子查询被展开,其中对象与主查询中对象直接进行对空值敏感的反关联操作。

互关联子查询的反嵌套
转换器对互关联子查询的反嵌套,会将子查询构造出一个内联视图,并将内联视图与主查询中的表进行管理。互关联子查询的反嵌套可以由参数_unnest_subquery 控制。这种转换属于启发式转换。
示例:
image.png
image.png
在上例中,关联谓词中存在子查询,该子查询被展开,其中对象与主查询中对象直接进行关联操作。

含有标量子查询的反嵌套
这种转换属于启发式转换。
image.png
image.png
image.png

在上例中, IN 子句中的子查询(INV)含有标量子查询(SCA),它也被查询转换器被展开, 标量子查询中的对象 T_USERS 直接与主查询中对象进行关联。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论