2016-01-13 81 views
0

我們有一位客戶在Oracle中創建了一個視圖效果不佳的客戶,並且查看視圖的SQL顯示他們正在視圖定義的WHERE子句中使用函數調用。這個功能相當密集,包括DELETEs和INSERTs。Oracle視圖在WHERE子句中使用函數...什麼性能影響?

我的直覺是,這不是一個好主意,但我不知道如何表達確切的原因......?

每次有人查詢視圖時,函數都會執行嗎?

每天刷新(例如)的物化視圖會更有意義,因此該函數每天只執行一次? (我想這將取決於被爆炸了所需的數據是否迄今爲止所有的時間...?)

感謝

+1

從SQL調用的函數只能在插入和刪除,如果它使用編譯指示自治事務聲明,否則它會得到ORA-14551。爲什麼他們需要一個每次查詢都會執行大量工作的視圖(這會發生,因爲視圖只是一個存儲查詢;可能每行取決於它的引用方式)? –

+0

謝謝@ alex-poole。我知道,這太瘋狂了......它已經被定義爲一個自治事務,但我正在努力將它們從視圖定義中移除並創建一個單獨的過程。你知道函數的執行頻率如何?每個用戶訪問該視圖是否會受到影響? – user2724502

+0

這取決於它是如何定義和調用的(是確定性的,例如?),但是如果它位於'where子句中,它可能會被每個用戶對每個查詢的查詢多次調用。即使一個用戶每天只查看一次視圖,它仍然是......不尋常的...至多也可能仍被稱爲多次。一個單獨的過程,可能通過工作調用,更有意義。或者可能是一個程序,檢查當天繁重的工作是否已經完成,如果沒有,那麼通過OUT sys-refcursor返回與視圖相同的數據,比如真的依賴。 –

回答

2

一個SELECT語句的WHERE子句中調用函數是一個壞消息。首先,該功能將被稱爲許多行,其中不是滿足查詢的條件,因爲該功能正在用於執行部分過濾。我曾經有過這看起來有點像

SELECT t.TRANSACTION_ID, t.SOME_OTHER_FIELD 
    FROM TRANSACTIONS t 
    WHERE MY_PACKAGE.IS_SALES_TRANSACTION(t.TRANSACTION_CODE) = TRUE AND 
     X <> Y AND 
     Y <> Z 

MY_PACKAGE.IS_SALES_TRANSACTION功能類似於

FUNCTION IS_SALES_TRANSACTION(pTransaction_code IN NUMBER) 
    RETURNS BOOLEAN IS 
BEGIN 
    IF pTransaction_code IN (10, 11, 12, 13) THEN 
    RETURN TRUE; 
    ELSE 
    RETURN FALSE; 
    END IF; 
END IS_SALES_TRANSACTION; 

我的小查詢花了約15分鐘的運行,這使得任何意義,我因爲查詢的SELECT語句表中只有約10,000,000箇中返回了約5000行。在完成代碼的一些工作之後,我發現這個函數被稱爲幾百萬次,並佔用了15分鐘執行時間的大部分時間。將SELECT語句更改爲

SELECT t.TRANSACTION_ID, t.SOME_OTHER_FIELD 
    FROM TRANSACTIONS t 
    WHERE t.TRANSACTION_CODE IN (10, 11, 12, 13) AND 
     X <> Y AND 
     Y <> Z 

導致光標在不到一秒內完成。

祝你好運。

相關問題