操作系統(tǒng):Windows XP
數(shù)據(jù)庫版本:SQL Server 2005
今天遇到一個(gè)SQL,過濾條件是自動(dòng)生成的,因此,沒法通過調(diào)整SQL的謂詞達(dá)到優(yōu)化的目的,只能去找SQL中的“大表”。有一個(gè)視圖返回的結(jié)果集比較大,如果能調(diào)整的話,也只能調(diào)整該視圖了。
看了一下該視圖的結(jié)構(gòu),里面還套用了另一層視圖,直接看最里層視圖的查詢SQL。
SELECT a.dfeesum_no , a.opr_amt - ISNULL(b.dec_pay, 0) - ISNULL(b.dec_corrpay, 0) - ISNULL(b.dec_deduamt, 0) dec_amt , a.dec_camt - ISNULL(b.dec_pay, 0) - a.dec_comprate * ISNULL(b.dec_deduamt, 0) dec_compamt , a.dec_ramt - ISNULL(b.dec_corrpay, 0) - ( a.dec_comprate - 1 ) * ISNULL(b.dec_deduamt, 0) dec_corramt , a.dec_qty - ISNULL(b.dec_qty, 0) - ISNULL(b.dec_deduqty, 0) opr_qty , ISNULL(b.dec_pay, 0) dec_pay , ISNULL(b.dec_corrpay, 0) dec_corrpay , ISNULL(b.dec_deduqty, 0) dec_deduqty , ISNULL(b.dec_deduamt, 0) dec_deduamt , ISNULL(b.dec_qty, 0) dec_qty FROM ctlm8686 a LEFT JOIN ( SELECT dfeesum_no , SUM(dec_ramt) dec_pay , SUM(dec_corramt) dec_corrpay , SUM(dec_qty) dec_qty , SUM(CASE WHEN flag_dedu = '1' THEN dec_deduamt ELSE 0 END) dec_deduamt , SUM(CASE WHEN flag_dedu = '1' THEN dec_deduqty ELSE 0 END) dec_deduqty FROM dfeepay_03 GROUP BY dfeesum_no ) b ON a.dfeesum_no = b.dfeesum_no UNION ALL SELECT a.dfeesum_no , a.dec_amt - ISNULL(b.dec_pay, 0) - ISNULL(b.dec_corrpay, 0) - ISNULL(b.dec_deduamt, 0) dec_amt , a.dec_compamt - ISNULL(b.dec_pay, 0) - a.dec_comprate * ISNULL(b.dec_deduamt, 0) dec_compamt , a.dec_corramt - ISNULL(b.dec_corrpay, 0) - ( a.dec_comprate - 1 ) * ISNULL(b.dec_deduamt, 0) dec_corramt , a.opr_qty - ISNULL(b.dec_qty, 0) - ISNULL(b.dec_deduqty, 0) opr_qty , ISNULL(b.dec_pay, 0) dec_pay , ISNULL(b.dec_corrpay, 0) dec_corrpay , ISNULL(b.dec_deduqty, 0) dec_deduqty , ISNULL(b.dec_deduamt, 0) dec_deduamt , ISNULL(b.dec_qty, 0) dec_qty FROM dfeeapp_03 a LEFT JOIN ( SELECT dfeesum_no , SUM(dec_ramt) dec_pay , SUM(dec_corramt) dec_corrpay , SUM(dec_qty) dec_qty , SUM(CASE WHEN flag_dedu = '1' THEN dec_deduamt ELSE 0 END) dec_deduamt , SUM(CASE WHEN flag_dedu = '1' THEN dec_deduqty ELSE 0 END) dec_deduqty FROM dfeepay_03 GROUP BY dfeesum_no ) b ON a.dfeesum_no = b.dfeesum_no
返回結(jié)果集有1433891行,其中
SELECT COUNT(*) FROM dfeepay_03 --1103914
SELECT COUNT(*) FROM ctlm8686 --1131586
SELECT COUNT(*) FROM dfeeapp_03--302305
上述SQL腳本中,子查詢是相同的,即對(duì)子查詢進(jìn)行了兩次掃描,可以考慮先讓dfeeapp_03和ctlm8686union all,再left join?dfeepay_03 。同時(shí),對(duì)于子查詢,先讓dfeepay_03 表先查詢出flag_dedu = '1'的數(shù)據(jù),就不用再進(jìn)行case when判斷了。
改寫后的SQL如下
SELECT a.dfeesum_no , a.opr_amt - ISNULL(b.dec_pay, 0) - ISNULL(b.dec_corrpay, 0) - ISNULL(b.dec_deduamt, 0) dec_amt , a.dec_camt - ISNULL(b.dec_pay, 0) - a.dec_comprate * ISNULL(b.dec_deduamt, 0) dec_compamt , a.dec_ramt - ISNULL(b.dec_corrpay, 0) - ( a.dec_comprate - 1 ) * ISNULL(b.dec_deduamt, 0) dec_corramt , a.dec_qty - ISNULL(b.dec_qty, 0) - ISNULL(b.dec_deduqty, 0) opr_qty , ISNULL(b.dec_pay, 0) dec_pay , ISNULL(b.dec_corrpay, 0) dec_corrpay , ISNULL(b.dec_deduqty, 0) dec_deduqty , ISNULL(b.dec_deduamt, 0) dec_deduamt , ISNULL(b.dec_qty, 0) dec_qty FROM ( SELECT a.dfeesum_no , a.opr_amt , a.dec_camt , a.dec_comprate , a.dec_ramt , a.dec_qty FROM ctlm8686 a UNION ALL SELECT a.dfeesum_no , a.dec_amt , a.dec_compamt , a.dec_comprate , a.dec_corramt , a.opr_qty FROM dfeeapp_03 a ) a LEFT JOIN ( SELECT dfeesum_no , SUM(dec_ramt) dec_pay , SUM(dec_corramt) dec_corrpay , SUM(dec_qty) dec_qty , SUM(dec_deduamt) dec_deduamt, SUM(dec_deduqty) dec_deduqty FROM dfeepay_03 WHERE flag_dedu = '1' GROUP BY dfeesum_no ) b ON a.dfeesum_no = b.dfeesum_no
跑這個(gè)視圖的查詢語句,從原來的一分半鐘降到一分鐘,對(duì)于整個(gè)SQL而言,則從原來跑幾分鐘的直接10S出結(jié)果。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
