1. 程式人生 > 其它 >記錄一次生產環境SQL優化

記錄一次生產環境SQL優化

針對多張表的關聯統計的一次SQL優化,主表(M表,500萬左右資料),關聯表1(C表,客戶表,千萬級資料),關聯表2(CER表,客戶員工關係表,千萬級資料),關聯表3(E表,員工表,資料量忽略不計),做了一次統計的SQL開發,主要就是一個優化的方法問題,以後寫SQL需要注意一下,使用的是Oracle的資料庫

一、第一版SQL編寫

1 SELECT COUNT(CASE WHEN M.INDI_ID = '0001' TEHN 1 END) COUNT1 FROM (
2 SELECT M.*, E.* FROM M 
3 LEFT JOIN C
4 ON M.CUST_NO = C.CUST_NO
5 LEFT JOIN CER 6 ON C.CUST_NO = CER.CUST_NO 7 LEFT JOIN E 8 ON CER.EMP_NO = E.EMP_NO 9 )

這種sql 是第一次寫的,本來是這樣看起來清晰一些,放到資料量大的情況下,直接查詢不出來了,好幾分鐘也出不來,只能進一步優化了,以後寫SQL避免這種從查詢出來的資料中在去巢狀查詢的方法,切記,萬不得已不要加這種巢狀查詢

二、第二版SQL優化

Oracle parallel() 並行優化

SELECT /*+parallel(M, 4)*/ COUNT(CASE WHEN M.INDI_ID = '0001' TEHN 1
END) COUNT1 FROM M LEFT JOIN C ON M.CUST_NO = C.CUST_NO LEFT JOIN CER ON C.CUST_NO = CER.CUST_NO LEFT JOIN E ON CER.EMP_NO = E.EMP_NO

去掉外面的巢狀from,直接加上並行優化,但是還是執行時間有些長,繼續優化,加上日期查詢條件欄位的索引,但是效果不是很明顯,跟搞資料開發的人討論,於是有了最終的優化方案

三、最終版SQL

Oracle use_hash(M, C, CER, E) 優化

SELECT /*+use_hash(M, C, CER, E)*/ COUNT
(CASE WHEN M.INDI_ID = '0001' TEHN 1 END) COUNT1 FROM M LEFT JOIN C ON M.CUST_NO = C.CUST_NO LEFT JOIN CER ON C.CUST_NO = CER.CUST_NO LEFT JOIN E ON CER.EMP_NO = E.EMP_NO

use_hash 官方說明

The USE_HASH hint causes Oracle to join each specified table with another row source with a hash join. The syntax of the USE_HASH hint is USE_HASH(table table) where table is a table to be joined to the row source resulting from joining the previous tables in the join order using a hash join.

翻譯過來就是:

USE_HASH 提示使 Oracle 通過雜湊連線將每個指定的表與另一個行源連線起來。 USE_HASH 提示的語法是 USE_HASH(table table),其中 table 是要連線到行源的表,該表是通過使用雜湊連線以連線順序連線先前的表而產生的。