2016-12-12 54 views
4

很久以前,在遠處的一個數據庫中,開發人員編寫了一個查詢,其中他/她依賴於寫入謂詞的順序。Oracle 12c嵌入式視圖評估

例如,

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; 
+0

你說在b表上可能有數百萬行('缺點是to_char可能會操作說一百萬行');一個表中有多少行,因爲會因爲發生隱式轉換而將to_number函數應用於該表中?如果表中有相似(或更多)的行數,那麼由於to_char,您可能會看到對性能沒有負面影響。 – Boneist

+1

或者,您可以在表a上創建一個僅包含數值的虛擬列(也可以索引該列),然後您的查詢可以簡化爲'從a.new_numeric_virtual_column = b.numeric_column的內連接b中選擇x; ' – Boneist

+0

現在,這是一個想法!我不得不承認我沒有考慮虛擬專欄!感謝您的建議! – 0909EM

回答

1

關於預測順序 - 看https://jonathanlewis.wordpress.com/2015/06/02/predicate-order-2/

您應該在最後一個查詢重寫然後根據DOC(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; 

壓制查詢unnesting或簡單地使用提示/*+ no_unnest*/使用rownum

+0

感謝您的鏈接喬納森劉易斯!在我的谷歌搜索中,我確實看到了rownum提到但在Oracle文檔中看不到它,謝謝你的鏈接。 – 0909EM