Oracle 12c Inline View Evaluation
Давным-давно в далекой базе данных разработчик написал запрос, в котором он / она полагался на порядок, в котором были написаны предикаты.
Например,
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, поэтому этот запрос прерывается с недопустимым исключением числа. Я знаю, что могу попытаться заставить 12c оценить предикаты по порядку, используя ORDERED_PREDICATES
намек на следующее
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;
1 ответ
О порядке предикатов - посмотрите на https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/
Вы должны переписать свой последний запрос для следующего использования rownum
в соответствии с документом ( https://docs.oracle.com/database/121/SQLRF/queries008.htm)
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*/