幫任總DBA太太最佳化條金融SQL案例(DM資料庫案例)

小至尖尖發表於2024-03-31

金融慢SQL:

SELECT *
FROM v_why
WHERE (
 (DECODE(AAA, 'N.A.', '19000101', AAA) <= REPLACE(20240328, '-', '')) AND (DECODE(AAA, 'N.A.', '19000101', AAA) >= REPLACE(20240328, '-', ''))
 OR ((DECODE(BBB, 'N.A.', '19000101', BBB) <= REPLACE(20240328, '-', '')) AND (DECODE(BBB, 'N.A.', '19000101', BBB) >= REPLACE(20240328, '-', '')))
 OR ((DECODE(CCC, 'N.A.', '19000101', CCC) <= REPLACE(20240328, '-', '')) AND (DECODE(CCC, 'N.A.', '19000101', CCC) >= REPLACE(20240328, '-', '')))
 OR ((DECODE(DDD, 'N.A.', '19000101', DDD) <= REPLACE(20240328, '-', '')) AND (DECODE(DDD, 'N.A.', '19000101', DDD) >= REPLACE(20240328, '-', '')))
        );

返回 91 行資料,執行時間要 35.4秒。

v_why 是張非常複雜檢視,不放執DM資料庫的執行計劃,1000多行,看不懂,這張檢視不是瓶頸。
SELECT COUNT(1) FROM  v_why;

上面SQL我也不知道為什麼慢,因為看不懂DM的執行計劃,只能改寫一個版本試試看。

等價改寫SQL:
        
SELECT * FROM (
WITH X AS (
    
    SELECT * FROM v_why
)
SELECT * FROM X WHERE (DECODE(AAA, 'N.A.', '19000101', AAA) = REPLACE(20240328, '-', ''))
UNION
SELECT * FROM X WHERE (DECODE(BBB, 'N.A.', '19000101', BBB) = REPLACE(20240328, '-', '')) 
UNION
SELECT * FROM X WHERE (DECODE(CCC, 'N.A.', '19000101', CCC) = REPLACE(20240328, '-', ''))
UNION
SELECT * FROM X WHERE (DECODE(DDD, 'N.A.', '19000101', DDD) = REPLACE(20240328, '-', ''))
);

改寫完以後 2.3秒能跑出結果,符合最佳化要求,差集比較後等價。
呦西,感覺DM的最佳化器不太行....

 

相關文章