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、比較に使用する値の 1 つをキャストします。欠点は、to_charたとえば100万行で動作する可能性があることです。次のインラインビューがおそらくより良い解決策だと思います。インライン ビューが最初に評価されることは保証されていますか?

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/を参照してください。

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

于 2016-12-12T10:02:09.653 に答える