4

很久以前,在一个很远很远的数据库中,一个开发人员编写了一个查询,他/她在该查询中依赖于谓词的写入顺序。

例如,

select x
  from a, b
 where NOT REGEXP_LIKE (a.column, '[^[:digit:]]')
   and a.char_column = b.numeric_column; 

(解释计划建议to_number转换将适用于a.char_column

我认为不仅仅是设计这个“正常工作”(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;
4

1 回答 1

1

关于谓词顺序 - 查看https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/

您应该rownum根据文档(https://docs.oracle.com/database/121/SQLRF/queries008.htm#SQLRF52358)将上一个查询重写为下一个查询

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*/

于 2016-12-12T10:02:09.653 回答