Oracle是否使用短路评估?

aoi*_*222 16 sql oracle

我有一个Oracle查询,其结构如下:

SELECT   *
FROM     table
WHERE    X='true' OR
         Y IN (complicated subquery)
Run Code Online (Sandbox Code Playgroud)

如果Oracle看到X确实等于'true',它仍然会尝试评估WHERE子句的Y IN(子查询)部分吗?此外,在诸如此类的语句中,子查询是否会对表中的每个条目执行多次?我会用以下的东西变得更好:

WITH subQ as (complicated subquery)
SELECT   *
FROM     table
WHERE    X='true' OR
         Y IN (SELECT id FROM subQ)
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 31

这取决于..通常,Oracle不保证SQL语句将使用短路评估(尽管PL/SQL可以保证执行短路评估).Oracle优化器可以以任何预期最有效的顺序自由地评估谓词.这可能意味着首先评估第一个谓词,只评估匹配行的第二个谓词,但完全可能发生相反的情况,或者Oracle将查询转换为某种类型,UNION并在组合结果之前完全评估两个谓词.

话虽这么说,如果优化器可以在编译时确定谓词将始终评估为TRUEFALSE,优化器应该将其视为常量.因此,例如,如果表上有一个约束阻止X值为'true',优化器根本不应该评估第二个谓词(尽管优化器的不同版本将具有不同的能力来检测某些东西在编译时是常量).

至于你问题的第二部分,没有看到查询计划,很难说.如果有更有效的评估方法,Oracle优化器往往非常擅长将查询从一种形式转换为另一种形式.但是,一般情况下,如果subQ要返回相对较多的行table,则将查询结构化为一个EXISTS而不是一个更有效IN.

  • @IsaacKleinman - 那仍然是SQL.如果你把条件放在PL/SQL中,你会看到短路.`begin if(1 <2或1/0 = 1)然后是dbms_output.put_line('Short circuit'); 万一; 结束;` (6认同)

Jon*_*ler 12

警告:Oracle不是我的主要专业领域.

基于成本的优化器应该知道成本X = 'true'低于子查询,因此它可能首先评估更简单的替代方案.但AND和OR条件SQL是不是短路一样&&,并||在C及其衍生物.

子查询可以是两种形式之一:相关和非相关.

  • 必须多次执行相关的子查询(这就是它们对性能有危险的原因),因为相关性意味着子查询结果在某种程度上取决于"当前正在评估"的行.
  • 非相关子查询只会执行一次.

示例相关子查询:

SELECT *
  FROM Table1
 WHERE X = 'true'
    OR Y IN (SELECT Z FROM Table2 WHERE Table2.A = Table1.B)
Run Code Online (Sandbox Code Playgroud)

示例非相关子查询:

SELECT *
  FROM Table1
 WHERE X = 'true'
    OR Y IN (SELECT Z FROM Table2 WHERE Table2.A > 13)
Run Code Online (Sandbox Code Playgroud)