我已經編寫了一個將文本值轉換爲日期/時間的標量函數(DYNAMIC_DATE
)。例如,DYANMIC_DATE('T-1')
(T-1 =今天減1 ='昨天')返回08-AUG-2012 00:00:00
。它也接受日期字符串:DYNAMIC_DATE('10/10/1974')
。WHERE子句中的Oracle標量函數導致性能較差
該函數利用CASE
語句解析唯一參數並計算相對於sysdate
的日期。
雖然它並沒有使用在其模式中的任何表,它利用TABLE
類型的存儲日期格式字符串:
TYPE VARCHAR_TABLE IS TABLE OF VARCHAR2(10);
formats VARCHAR_TABLE := VARCHAR_TABLE ('mm/dd/rrrr','mm-dd-rrrr','rrrr/mm/dd','rrrr-mm-dd');
當我使用SELECT
子句中的功能,在<1秒查詢返回:
SELECT DYNAMIC_DATE('MB-1') START_DATE, DYNAMIC_DATE('ME-1') END_DATE
FROM DUAL
如果我用它對付我們的約會維度表(共91311條記錄),查詢完成了<1秒:
SELECT count(1)
from date_dimension
where calendar_dt between DYNAMIC_DATE('MB-1') and DYNAMIC_DATE('ME-1')
其他人,但是,如果它是用來對付一個更大的表正與功能問題(26301317個記錄):
/*
cost: 148,840
records: 151,885
time: ~20 minutes
*/
SELECT count(1)
FROM ORDERS ord
WHERE trunc(ord.ordering_date) between DYNAMIC_DATE('mb-1') and DYNAMIC_DATE('me-1')
然而,相同的查詢,使用「硬編碼」日期,退貨相當迅速:
/*
cost: 144,257
records: 151,885
time: 62 seconds
*/
SELECT count(1)
FROM ORDERS ord
WHERE trunc(ord.ordering_date) between to_date('01-JUL-2012','dd-mon-yyyy') AND to_date('31-JUL-2012','dd-mon-yyyy')
供應商的香草安裝不包括在ORDERING_DATE
領域的指標。
的解釋這兩個查詢計劃是相似的:
與功能:
通過硬編碼日期:
- 是在
DYNAMIC_DATE
功能被在WHERE
一再呼籲條款? - 還有什麼可以解釋這種差距?
** **編輯
甲NONUNIQUE
索引加入到訂單表。兩個查詢都在1秒內執行<。兩種方案都是一樣的(方法),但具有該功能的方案成本較低。
我從功能中刪除了DETERMINISTIC
關鍵字;查詢在1秒內執行<。
- 問題是真的與函數還是與表相關?
- 從現在開始的3年,這張表甚至更大時,如果我不包含關鍵字
DETERMINISTIC
,查詢性能會受損嗎? DETERMINISTIC
關鍵字對函數結果有任何影響嗎?如果我明天運行DYNAMIC_DATE('T-1')
,我是否會得到與今天運行時相同的結果(08/09/2012)?如果是這樣,這種方法將無法工作。
如果解釋計劃是相似的,這是否意味着它們不相同?如果它們不相同,你可以發佈這兩個計劃嗎? – 2012-08-09 15:09:09
計劃是完全相同的(意思是步驟);只有總成本不同。 – craig 2012-08-09 15:16:16
「ORDERS」中有多少條記錄? – Ollie 2012-08-09 15:17:54