操作系統:Windows XP
數據庫版本:SQL Server 2005
今天遇到一個SQL,過濾條件是自動生成的,因此,沒法通過調整SQL的謂詞達到優化的目的,只能去找SQL中的“大表”。有一個視圖返回的結果集比較大,如果能調整的話,也只能調整該視圖了。
看了一下該視圖的結構,里面還套用了另一層視圖,直接看最里層視圖的查詢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
返回結果集有1433891行,其中
SELECT COUNT(*) FROM dfeepay_03 --1103914
SELECT COUNT(*) FROM ctlm8686 --1131586
SELECT COUNT(*) FROM dfeeapp_03--302305
上述SQL腳本中,子查詢是相同的,即對子查詢進行了兩次掃描,可以考慮先讓dfeeapp_03和ctlm8686union all,再left join?dfeepay_03 。同時,對于子查詢,先讓dfeepay_03 表先查詢出flag_dedu = '1'的數據,就不用再進行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
跑這個視圖的查詢語句,從原來的一分半鐘降到一分鐘,對于整個SQL而言,則從原來跑幾分鐘的直接10S出結果。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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