【问题标题】:How will Oracle handle a where clause condition comparing against a subquery with a constant result?Oracle 将如何处理 where 子句条件与具有恒定结果的子查询进行比较?
【发布时间】:2010-12-16 04:01:41
【问题描述】:

假设我有以下内容:

select primary_id
from myschema.table_a
where row_changed_date > ( select last_refreshed
                           from myschema.last_refresh lr
                           where asset_type = 0 );

子查询的结果不会在资产之间改变。从技术上讲,我想直接与常量值进行比较,但我不想运行单独的查询来获取该常量。 Oracle 会为每次迭代运行子查询吗?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: sql oracle optimization


    【解决方案1】:

    您需要确保您的子查询返回单行,或者使用限定比较:

    WHERE row_changed_date > ALL ( SELECT last_refreshed ... )
    

    或者:

    WHERE row_changed_date > (SELECT MAX(last_refreshed) ...)
    

    假设asset_typelast_refresh 表中的一列,那么Oracle 将计算一次子查询。如果它实际上是table_a 表中的一列,那么你有一个相关的子查询;必须按行评估。

    这个答案实际上与 DBMS 无关 - 规则适用于 Oracle 以及其他 SQL DBMS。

    【讨论】:

    • 是的,将这些表别名添加到子查询中的列更安全。
    【解决方案2】:

    在您使用子查询的示例中——不,Oracle 不会为每一行运行子查询。不过,相关的子查询会。

    用途:

    SELECT a.primary_id
      FROM MYSCHEMA.TABLE_A a 
      JOIN MYSCHEMA.LAST_REFRESH lr ON lr.last_refreshed < a.row_changed_date
                                   AND lr.asset_type = 0
    

    使用 WHERE 的替代版本:

    SELECT a.primary_id
      FROM MYSCHEMA.TABLE_A a 
      JOIN MYSCHEMA.LAST_REFRESH lr ON lr.last_refreshed < a.row_changed_date
     WHERE lr.asset_type = 0
    

    由于使用了 INNER JOIN,这两种查询版本之间的结果或性能没有差异。如果使用 OUTER JOINS (LEFT, RIGHT),情况就不是这样了。

    【讨论】:

      猜你喜欢
      • 2020-07-08
      • 1970-01-01
      • 2011-03-09
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多