3.3數據抽取和上載時的SQL優化
3.3.1 WHERE子句中的連接順序
ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其它WHERE條件之前,那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
低效:SELECT * FROM EMP E WHERE SAL > 50000 AND JOB = ‘MANAGER’ AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);
高效:SELECT * FROM EMP E WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO) AND SAL > 50000 AND JOB = ‘MANAGER’;
3.3.2 刪除全表時用TRUNCATE替代DELETE
當DELETE刪除表中的記錄時,有回滾段(rollback segments ) 用來存放可以被恢復的信息,而當運用TRUNCATE時,回滾段不再存放任何可被恢復的信息,所以執行時間也會很短。同時需要注意TRUNCATE只在刪除全表時適用,因為TRUNCATE是DDL而不是DML。
3.3.3 盡量多使用COMMIT
ETL中同一個過程的數據操作步驟很多,數據倉庫采用的是數據抽取后分析模型重算的原理,所以對數據的COMMIT不像業務系統為保證數據的完整和一致性而需要某個操作過程全部完成才能進行,只要有可能就在程序中對每個DELETE、INSERT和UPDATE操作盡量多使用COMMIT, 這樣系統性能會因為COMMIT所釋放的資源而大大提高。
3.3.4 用EXISTS替代IN
在許多基于基礎表的查詢中,為了滿足一個條件往往需要對另一個表進行聯接,例如在ETL過程寫數據到模型時經常需要關聯10個左右的維表,在這種情況下,使用EXISTS而不用IN將提高查詢的效率。
3.3.5 用NOT EXISTS替代NOT IN
子查詢中,NOT IN子句將執行一個內部的排序和合并,無論在哪種情況下,NOT IN都是最低效的,因為它對子查詢中的表執行了一個全表遍歷。用NOT EXISTS替代NOT IN將提高查詢的效率。
3.3.6 優化GROUP BY
提高GROUP BY 語句的效率,可以通過將不需要的記錄在GROUP BY 之前過濾掉。
低效: SELECT JOB , AVG(SAL) FROM EMP GROUP BY JOB HAVING JOB = ‘PRESIDENT’ OR JOB = ‘MANAGER’
高效: SELECT JOB , AVG(SAL) FROM EMP WHERE JOB = ‘PRESIDENT’ OR JOB = ‘MANAGER’ GROUP BY JOB
3.3.7 有條件的使用UNION-ALL 替換UNION
ETL過程針對多表連接操作的情況很多,有條件的使用UNION-ALL 替換UNION的前提是:所連接的各個表中無主關鍵字相同的記錄,因為UNION ALL 將重復輸出兩個結果集合中相同記錄。
當SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合并,然后在輸出最終結果前進行排序。如果用UNION ALL替代UNION,這樣排序就不是必要了,效率就會因此得到提高3-5倍。
3.3.8 分離表和索引
總是將你的表和索引建立在不同的表空間內,決不要將不屬于ORACLE內部系統的對象存放到SYSTEM表空間里。同時確保數據表空間和索引表空間置與不同的硬盤控制卡控制的硬盤上。
文章來源于領測軟件測試網 http://www.kjueaiud.com/