文章詳情頁(yè)
Oracle SQL性能優(yōu)化系列介紹(下)
瀏覽:6日期:2023-11-12 17:29:31
相關(guān)文章:Oracle SQL性能優(yōu)化系列介紹(上) 6. SELECT子句中避免使用 ‘ * ‘ 當(dāng)你想在SELECT子句中列出所有的COLUMN時(shí),使用動(dòng)態(tài)SQL列引用 ‘*' 是一個(gè)方便的方法.不幸的是,這是一個(gè)非常低效的方法. 實(shí)際上,Oracle在解析的過程中, 會(huì)將'*' 依次轉(zhuǎn)換成所有的列名, 這個(gè)工作是通過查詢數(shù)據(jù)字典完成的, 這意味著將耗費(fèi)更多的時(shí)間。 7. 減少訪問數(shù)據(jù)庫(kù)的次數(shù) 當(dāng)執(zhí)行每條SQL語(yǔ)句時(shí), ORACLE在內(nèi)部執(zhí)行了許多工作: 解析SQL語(yǔ)句, 估算索引的利用率, 綁定變量 , 讀數(shù)據(jù)塊等等. 由此可見, 減少訪問數(shù)據(jù)庫(kù)的次數(shù) , 就能實(shí)際上減少ORACLE的工作量。 例如, 以下有三種方法可以檢索出雇員號(hào)等于0342或0291的職員。 方法1 (最低效) SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 342; SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 291;方法2 (次低效) DECLARE CURSOR C1 (E_NO NUMBER) IS SELECT EMP_NAME,SALARY,GRADE FROM EMP WHERE EMP_NO = E_NO; BEGIN OPEN C1(342); FETCH C1 INTO …,..,.. ; ….. OPEN C1(291); FETCH C1 INTO …,..,.. ; CLOSE C1; END;方法3 (高效) SELECT A.EMP_NAME , A.SALARY , A.GRADE, B.EMP_NAME , B.SALARY , B.GRADE FROM EMP A,EMP B WHERE A.EMP_NO = 342 AND B.EMP_NO = 291; 注重: 在SQL*Plus , SQL*Forms和Pro*C中重新設(shè)置ARRAYSIZE參數(shù), 可以增加每次數(shù)據(jù)庫(kù)訪問的檢索數(shù)據(jù)量 ,建議值為200。8. 使用DECODE函數(shù)來減少處理時(shí)間 使用DECODE函數(shù)可以避免重復(fù)掃描相同記錄或重復(fù)連接相同的表。 例如: SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 AND ENAME LIKE ‘SMITH%'; SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE ‘SMITH%';你可以用DECODE函數(shù)高效地得到相同結(jié)果 SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT, COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT, SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL, SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL FROM EMP WHERE ENAME LIKE ‘SMITH%';類似的,DECODE函數(shù)也可以運(yùn)用于GROUP BY 和ORDER BY子句中。9. 整合簡(jiǎn)單,無關(guān)聯(lián)的數(shù)據(jù)庫(kù)訪問 假如你有幾個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)查詢語(yǔ)句,你可以把它們整合到一個(gè)查詢中(即使它們之間沒有關(guān)系) 例如: SELECT NAME FROM EMP WHERE EMP_NO = 1234; SELECT NAME FROM DPT WHERE DPT_NO = 10 ; SELECT NAME FROM CAT WHERE CAT_TYPE = ‘RD';上面的3個(gè)查詢可以被合并成一個(gè): SELECT E.NAME , D.NAME , C.NAME FROM CAT C , DPT D , EMP E,DUAL X WHERE NVL(‘X',X.DUMMY) = NVL(‘X',E.ROWID(+)) AND NVL(‘X',X.DUMMY) = NVL(‘X',D.ROWID(+)) AND NVL(‘X',X.DUMMY) = NVL(‘X',C.ROWID(+)) AND E.EMP_NO(+) = 1234 AND D.DEPT_NO(+) = 10 AND C.CAT_TYPE(+) = ‘RD';(譯者按: 雖然采取這種方法,效率得到提高,但是程序的可讀性大大降低,所以讀者 還是要權(quán)衡之間的利弊) 10. 刪除重復(fù)記錄 最高效的刪除重復(fù)記錄方法 ( 因?yàn)槭褂昧薘OWID) DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);11. 用TRUNCATE替代DELETE 當(dāng)刪除表中的記錄時(shí),在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復(fù)的信息. 假如你沒有COMMIT事務(wù),ORACLE會(huì)將數(shù)據(jù)恢復(fù)到刪除之前的狀態(tài)(準(zhǔn)確地說是恢復(fù)到執(zhí)行刪除命令之前的狀況) ,而當(dāng)運(yùn)用TRUNCATE時(shí), 回滾段不再存放任何可被恢復(fù)的信息.當(dāng)命令運(yùn)行后,數(shù)據(jù)不能被恢復(fù).因此很少的資源被調(diào)用,執(zhí)行時(shí)間也會(huì)很短。(注: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML) 12. 盡量多使用COMMIT 只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也會(huì)因?yàn)镃OMMIT所釋放的資源而減少,COMMIT所釋放的資源: a. 回滾段上用于恢復(fù)數(shù)據(jù)的信息。 b. 被程序語(yǔ)句獲得的鎖。 c. redo log buffer 中的空間。 d. Oracle為治理上述3種資源中的內(nèi)部花費(fèi)。 (注:在使用COMMIT時(shí)必須要注重到事務(wù)的完整性,現(xiàn)實(shí)中效率和事務(wù)完整性往往是魚和熊掌不可得兼)
標(biāo)簽:
Oracle
數(shù)據(jù)庫(kù)
排行榜
