Oracle 如何执行 OR 条件验证?
How does Oracle perform OR condition validation?
在 Java 中,逻辑 OR 条件的行为是,如果第一个条件是 true
,则它不会评估第二个条件。
例如:
int a = 10;
if (a == 10 || a == 0) {
// Logic
}
Java 不评估第二个测试 (a == 0
) 因为第一个条件 (a == 10
) 是 true
.
如果我们有这样一个 Oracle SQL 语句:
select * from student where city = :city and
(:age is null or age > :age)
(age > :age or :age is null)
是如何评价的?如果参数 :age
是 NULL
,那么它是否也评估第二个条件?
数据库成本优化器将在构建查询执行时考虑许多因素。可能最重要的是在相关列上存在索引。它将根据测试的选择性来决定顺序,并可以在不同的时间以不同的顺序执行它们。由于 SQL 是声明性而非过程性语言,因此您通常无法控制评估这些条件的方式。
您可以提供一些 "hints" 来建议特定的执行顺序,但您可能会对性能产生不利影响。
PL/SQL
在PL/SQL中,Oracle OR是另一个短路评估的例子。 Oracle PL/SQL Language Fundamentals 说(部分)
Short-Circuit Evaluation
When evaluating a logical expression, PL/SQL uses short-circuit evaluation. That is, PL/SQL stops evaluating the expression as soon as it can determine the result. Therefore, you can write expressions that might otherwise cause errors.
SQL
但是,在常规 SQL 中,OR 可能 以任一顺序计算。正如 @JonHeller 在他的评论 中指出的那样,这个问题中的表达式是安全的,如果处理潜在的被 0 的除法,则需要更加谨慎。
让 Oracle 为您做决定。大多数时候它会做出更好的决定。在这种情况下,甚至还有一个将 null 测试与测试值结合起来的构造。
替换
:age is null or age > :age
有
age > nvl(:age, age - 1)
在 Java 中,逻辑 OR 条件的行为是,如果第一个条件是 true
,则它不会评估第二个条件。
例如:
int a = 10;
if (a == 10 || a == 0) {
// Logic
}
Java 不评估第二个测试 (a == 0
) 因为第一个条件 (a == 10
) 是 true
.
如果我们有这样一个 Oracle SQL 语句:
select * from student where city = :city and
(:age is null or age > :age)
(age > :age or :age is null)
是如何评价的?如果参数 :age
是 NULL
,那么它是否也评估第二个条件?
数据库成本优化器将在构建查询执行时考虑许多因素。可能最重要的是在相关列上存在索引。它将根据测试的选择性来决定顺序,并可以在不同的时间以不同的顺序执行它们。由于 SQL 是声明性而非过程性语言,因此您通常无法控制评估这些条件的方式。
您可以提供一些 "hints" 来建议特定的执行顺序,但您可能会对性能产生不利影响。
PL/SQL
在PL/SQL中,Oracle OR是另一个短路评估的例子。 Oracle PL/SQL Language Fundamentals 说(部分)
Short-Circuit Evaluation
When evaluating a logical expression, PL/SQL uses short-circuit evaluation. That is, PL/SQL stops evaluating the expression as soon as it can determine the result. Therefore, you can write expressions that might otherwise cause errors.
SQL
但是,在常规 SQL 中,OR 可能 以任一顺序计算。正如 @JonHeller 在他的评论 中指出的那样,这个问题中的表达式是安全的,如果处理潜在的被 0 的除法,则需要更加谨慎。
让 Oracle 为您做决定。大多数时候它会做出更好的决定。在这种情况下,甚至还有一个将 null 测试与测试值结合起来的构造。
替换
:age is null or age > :age
有
age > nvl(:age, age - 1)