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

oracle 查询转换简单说明-6

原创 不吃草的牛_Nick 2023-09-10
165

1.1.1   子查询合并

子查询合并(Subquery Coalescing)的目的是将等价的半连接以及反连接子查询组合到同一个查询块中。应用这种自11.2版本起可用的基于启发式的查询变换,其主要目的是减少表访问的数量,从而减少连接的数量。

 

下面的例子来自subquery_coalescing.sql脚本,演示了这种查询转换是如何工作的。注意,两个相互关联的子查询处理相同的数据,只是限制条件有所区别:

SELECT *

FROM t1

WHERE EXISTS(SELECT 1 FROM t2 WHERE t2.id = t1.id AND t2.n>10)

   OR EXISTS(SELECT 1 FROM t2 WHERE t2.id = t1.id AND t2.n<100);

 

子查询合并组合两个子查询并产生以下查询:

SELECT *

FROM t1

WHERE EXISTS(SELECT 1 FROM t2 WHERE t2.id = t1.id AND (t2.n >10 OR t2.n<100));

 

通过子查询展开,可以将查询进一步转化成以下形式。注意,正如在上一节中所解释的,下面的查询使用一个特殊的运算符 (s=)来实现半连接。这个运算符仅可以在SQL引擎内部使用,并非那种可以在书写SQL语句时指定的语法的一部分:

SELECT t1.*

FROM t1,t2

WHERE t1.id s= t2.id AND (t2.n > 10 OR t2.n<100);

 

1.1.1   使用窗口函数移除子查询

使用窗口函数移除子查询(Subquery Removal Using Window Function)的目的是使用窗口函数替换包含聚合函数的子查询。这是一种基于启发式的查询转换,可以在一个查询块包含所有出现在一个子查询中的表和谓词时应用。

 

下面的例子基于subquery_removal.sql脚本,演示了这种查询转换是如何工作的。注意,在顶层查询和子查询中都引用了t2表:

SELECT t1.id, t1.n, t2.id, t2.n

FROM t1, t2

WHERE t1.id = t2.t1_id

AND t2.n = (SELECT max(n) FROM t2 WHERE t2.t1_id = t1.id);

 

查询转换移除子查询,并产生接下来的查询。注意CASE表达式是如何用来生成某种标志的。这种标志用来识别那些满足在原始查询中由子查询指定的限制条件的记录:

SELECT t1.id, t1.n, t2.id, t2.n

FROM (SELECT t1.id as t1_id,t1.n as t1_n, t2.id as t2_id, t2.n as t2_n,

        case t2.n

          when max(t2.n) over (partition by t2.t1_id) then 1

        end as max

      from t2,t1

      WHERE t1.id = t2.t1_id) vw_wif

WHERE max is not null);

 

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

评论