一個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
導致光標在不到一秒內完成。
祝你好運。
從SQL調用的函數只能在插入和刪除,如果它使用編譯指示自治事務聲明,否則它會得到ORA-14551。爲什麼他們需要一個每次查詢都會執行大量工作的視圖(這會發生,因爲視圖只是一個存儲查詢;可能每行取決於它的引用方式)? –
謝謝@ alex-poole。我知道,這太瘋狂了......它已經被定義爲一個自治事務,但我正在努力將它們從視圖定義中移除並創建一個單獨的過程。你知道函數的執行頻率如何?每個用戶訪問該視圖是否會受到影響? – user2724502
這取決於它是如何定義和調用的(是確定性的,例如?),但是如果它位於'where子句中,它可能會被每個用戶對每個查詢的查詢多次調用。即使一個用戶每天只查看一次視圖,它仍然是......不尋常的...至多也可能仍被稱爲多次。一個單獨的過程,可能通過工作調用,更有意義。或者可能是一個程序,檢查當天繁重的工作是否已經完成,如果沒有,那麼通過OUT sys-refcursor返回與視圖相同的數據,比如真的依賴。 –