Oracle 12c 内联视图评估
Oracle 12c Inline View Evaluation
很久以前,在一个很远很远的数据库中,一位开发人员编写了一个查询,其中 he/she 依赖于谓词的写入顺序。
例如,
select x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column;
(说明计划建议将 to_number
转换应用于 a.char_column
)
我想的不仅仅是设计这个"just works"(Oracle 11g)。但是,在 Oracle 12c 中 运行 时不遵守谓词的顺序,因此此查询因无效数字异常而中断。我知道我可以尝试使用 ORDERED_PREDICATES
提示强制 12c 按顺序评估谓词
select /*+ ORDERED_PREDICATES +*/ x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column
.. 或使用 to_char
转换其中一个值进行比较。缺点是 to_char
可以对一百万行进行操作。我认为以下内联视图可能是更好的解决方案。我能保证内联视图首先被评估吗?
select x
from b
inner join (
select only_rows_with_numeric_values as numeric_column
from a
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
) c
on c.numeric_column = b.numeric_column;
关于谓词顺序 - 查看 https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/
您应该根据 doc(https://docs.oracle.com/database/121/SQLRF/queries008.htm#SQLRF52358)
使用 rownum
将上一个查询重写为下一个
select x
from b
inner join (
select only_rows_with_numeric_values as numeric_column,
rownum
from a
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
) c
on c.numeric_column = b.numeric_column;
抑制查询取消嵌套或简单地使用提示 /*+ no_unnest*/
很久以前,在一个很远很远的数据库中,一位开发人员编写了一个查询,其中 he/she 依赖于谓词的写入顺序。
例如,
select x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column;
(说明计划建议将 to_number
转换应用于 a.char_column
)
我想的不仅仅是设计这个"just works"(Oracle 11g)。但是,在 Oracle 12c 中 运行 时不遵守谓词的顺序,因此此查询因无效数字异常而中断。我知道我可以尝试使用 ORDERED_PREDICATES
提示强制 12c 按顺序评估谓词
select /*+ ORDERED_PREDICATES +*/ x
from a, b
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
and a.char_column = b.numeric_column
.. 或使用 to_char
转换其中一个值进行比较。缺点是 to_char
可以对一百万行进行操作。我认为以下内联视图可能是更好的解决方案。我能保证内联视图首先被评估吗?
select x
from b
inner join (
select only_rows_with_numeric_values as numeric_column
from a
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
) c
on c.numeric_column = b.numeric_column;
关于谓词顺序 - 查看 https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/
您应该根据 doc(https://docs.oracle.com/database/121/SQLRF/queries008.htm#SQLRF52358)
使用rownum
将上一个查询重写为下一个
select x
from b
inner join (
select only_rows_with_numeric_values as numeric_column,
rownum
from a
where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
) c
on c.numeric_column = b.numeric_column;
抑制查询取消嵌套或简单地使用提示 /*+ no_unnest*/