確定性函式改造sql
確定性函式改造
前提
往往我們在編寫sql時,會對一些特殊重複計算處理用到函式。函式是資料庫一個重要特性,可以讓使用者高效的重複使用資料計算,但函式有些執行速度要比想象的慢,尤其在條件篩選方面會有潛在的效能問題。
說明
確定性函式用關鍵詞Deterministic標識,表示函式的返回值完全由輸入引數決定。
確定性函式的優點:
其返回結果能夠進行快取處理以提升效能。
但是要注意:
是不是一個確定性函式是需要使用者來負責的,就是說對函式進行編譯的時候不會檢查出這個函式是否是確定性的,也就是必須保證只要使用特定的輸入值集,那麼不管何時呼叫,確定性函式始終都會返回相同的結果。
例項
原始sql
SELECT '20221231' AS mdtrdt, mdacno, mdsbno, mdcyno, mditcd, mdacbl AS mdcubl, mdlabl, mdopdt, mdvldt, mdmadt, CONVERT_FDMD_PERD_DETERMINISTIC(mdperd, mdvldt), mdcldt, TRIM(mdinkd), NVL(mdinrt, 0), mdstcd, mdcuno, mdaucd, cust_acct, sub_acct_seq_no FROM in_fdmdl1 ,(SELECT business_code, node_type FROM tb_crinit2 t WHERE business_state = '1' START WITH (business_code = PROFIT_CONSTANTS2.BUSI_CODE_FDCC OR business_code = PROFIT_CONSTANTS2.BUSI_CODE_FDPS) CONNECT BY parent_id = PRIOR business_code) WHERE in_date = '20221231' AND mdstcd NOT IN ('H', 'I', 'Q') AND (mdcldt = '0' OR mdcldt >= FUN_DAY_YESTERDAY('20221231')) AND mditcd = business_code AND node_type = '02' AND mdvldt <= '20221231';
原執行計劃
1 #NSET2: [2019, 49679->5908849, 1058] 2 #PRJT2: [2019, 49679->5908849, 1058]; exp_num(19), is_atom(FALSE) 3 #HASH2 INNER JOIN: [2019, 49679->5908849, 1058]; KEY_NUM(1); 4 #PRJT2: [3, 4->35, 200]; exp_num(1), is_atom(FALSE) 5 #SLCT2: [3, 4->35, 200]; 6 #HIERARCHICAL QUERY: [3, 85->51, 200]; key_num(0) 7 #UNION FOR OR2: [1, 12->2, 200]; key_num(1) 8 #BLKUP2: [1, 6->1, 200]; IDX_TB_CRINIT2(TB_CRINIT2) 9 #SLCT2: [1, 6->1, 200]; 10 #SSCN: [1, 6->241, 200]; IDX_TB_CRINIT2(TB_CRINIT2) 11 #BLKUP2: [1, 6->1, 200]; IDX_TB_CRINIT2(TB_CRINIT2) 12 #SLCT2: [1, 6->1, 200]; 13 #SSCN: [1, 6->241, 200]; IDX_TB_CRINIT2(TB_CRINIT2) 14 #SLCT2: [1, 7->49, 200]; 15 #SSCN: [1, 7->12291, 200]; I_TBCRINIT2_LH(TB_CRINIT2) 16 #HASH RIGHT SEMI JOIN2: [1961, 312628->5908923, 858]; key_num(1) (ANTI), 17 #CONST VALUE LIST: [1, 3->3, 48]; row_num(3), col_num(1), 18 #SLCT2: [1961, 312628->5918256, 858]; 19 #CSCN2: [1961, 6759529->6759529, 858]; INDEX34435162_34434582(IN_FDMDL1_IN_FDMDL1_P20221231)
同時分析下ET,確定慢的部分
LINEID OP TIME(US) PERCENT RANK SEQ N_ENTER ---------- --------- -------------------- ------- -------------------- ----------- ----------- 1 PRJT2 1 0% 20 4 4 2 BLKUP2 7 0% 18 8 4 3 SLCT2 7 0% 18 5 4 4 CONSTV 8 0% 17 17 2 5 UNION_OR2 11 0% 16 7 7 6 SSCN 18 0% 15 10 2 7 SLCT2 52 0% 14 9 4 8 SLCT2 58 0% 13 12 4 9 CNNTB 97 0% 12 6 72 10 SLCT2 113 0% 11 14 169 11 SSCN 1494 0% 10 15 102 LINEID OP TIME(US) PERCENT RANK SEQ N_ENTER ---------- ------ -------------------- ------- -------------------- ----------- ----------- 12 SSCN 19134 0.02% 9 13 2 13 DLCK 21836 0.03% 8 0 2373 14 BLKUP2 23039 0.03% 7 11 4 15 HRS2 291446 0.36% 6 16 13524 16 HI3 607385 0.75% 5 3 13524 17 SLCT2 3396682 4.22% 4 18 13522 18 NSET2 5430177 6.74% 3 1 9133 19 CSCN2 22166928 27.51% 2 19 6761 20 PRJT2 48604664 60.33% 1 2 13522 20 rows got
分析發現in_fdmdl1分割槽表的IN_FDMDL1_IN_FDMDL1_P20221231產生的是全表掃描,藉此我們先分析主驅動表的where篩選。
實驗查詢發現篩選度很高,但沒有走聯合索引,而當我們把函式不確定值帶入返回的確認實際值時,走了索引且速度很快。
試驗1:修改函式的實現方式
將FUN_DAY_YESTERDAY轉化為TO_CHAR(add_days(to_date(p_date,'YYYY-MM-DD'),-1),'YYYYMMDD')
走了索引且速度很快
試驗2:將sql改寫成動態拼串,然後用execute immediate執行拼串sql,走了索引且速度依然很快。
初步總結
透過試驗1.2分析:由於分析器無法確認函式內操作而造成每次查詢此sql都要重新評估執行計劃。
再最佳化
而如何可以在不修改原有函式的處理方式或者不改成動態sql執行的方式,來最佳化現有sql速度呢?
根據函式內分析,我們可以利用確認性函式。
修改函式將FUN_DAY_YESTERDAY內轉化為確認性函式,且命名為將FUN_DAY_YESTERDAY_DETERMINISTIC。
create or replace function FUN_DAY_YESTERDAY_DETERMINISTIC P_DATE VARCHAR2, P_TYPE INTEGER :=1, RETURN VARCHAR2 DETERMINISTIC AS .... BEGIN ... END;
修改後試驗發現,速度提升到秒級。
總結
對於使用頻繁的函式,確定性函式的定義將在很大的程度上提高了資料庫的效能。
DM 武漢達夢資料庫股份有限公司
24小時免費服務熱線:400 991 6599
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70002866/viewspace-2991129/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle函式的確定性Oracle函式
- 確定性推理
- 確定性投資的框架框架
- SQL函式之日期函式SQL函式
- sql函式SQL函式
- 【SQL】19 SQL函式SQL函式
- 淺談系統的不確定性與穩定性
- SQL--函式SQL函式
- sql 日期函式SQL函式
- T-SQL——函式——字串操作函式SQL函式字串
- 專訪Michael Jordan:AI的分散式決策與不確定性AI分散式
- 科技行業中期策略:在不確定性中尋找確定性變化(附下載)行業
- 普華永道:解析無人駕駛技術的確定性與不確定性(附下載)
- 【SQL基礎】T-SQL函式型別——系統函式SQL函式型別
- T-SQL——函式——時間操作函式SQL函式
- Sql 中的 left 函式、right 函式SQL函式
- Sql Server函式全解(1):字串函式SQLServer函式字串
- Sql Server函式全解(一)字串函式SQLServer函式字串
- sql優化用group by 函式代替分析函式SQL優化函式
- SQL LEN()函式用法SQL函式
- SQL 視窗函式SQL函式
- Spark Sql 函式使用SparkSQL函式
- Sql字串操作函式SQL字串函式
- PL/SQL 函式 包SQL函式
- Sql Server 日期函式SQLServer函式
- SQL SERVER 字串函式SQLServer字串函式
- Sql時間函式SQL函式
- 區塊鏈的確定性問題區塊鏈
- 區塊鏈共識的確定性區塊鏈
- Oracle 遷移到 OB 過程中的函式改造案例Oracle函式
- Sql Server函式全解(2):數學函式SQLServer函式
- Sql Server函式全解(5):系統函式SQLServer函式
- MogDB/openGauss的三種函式穩定性關鍵字函式
- Spark SQL 開窗函式SparkSQL函式
- SQL Server常用函式整理SQLServer函式
- SQL中的cast()函式SQLAST函式
- SQL CHARINDEX函式的使用SQLIndex函式
- Oracle PL/SQL 之 函式OracleSQL函式