通过调整表union all的顺序优化SQL
2014-11-25 18:04
330 查看
原文:通过调整表union all的顺序优化SQL 操作系统:Windows XP
数据库版本:SQL Server 2005
今天遇到一个SQL,过滤条件是自动生成的,因此,没法通过调整SQL的谓词达到优化的目的,只能去找SQL中的“大表”。有一个视图返回的结果集比较大,如果能调整的话,也只能调整该视图了。
看了一下该视图的结构,里面还套用了另一层视图,直接看最里层视图的查询SQL。
返回结果集有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如下
跑这个视图的查询语句,从原来的一分半钟降到一分钟,对于整个SQL而言,则从原来跑几分钟的直接10S出结果。
数据库版本: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出结果。
相关文章推荐
- 通过调整表union all的顺序优化SQL
- sql优化实战:把full join改为left join +union all(从5分钟降为10秒)
- 【SQL优化】B树索引位图转换及OR到UNION(ALL)的改写
- oracle sql优化案例2(RBO下调整表连接的顺序)
- sql中union all 语法报错可通过改变方式
- SQL优化及UNION ALL替代UNION
- mysql通过将or改成union来优化sql性能问题一例
- SQL优化及UNION ALL替代UNION
- 使用or展开进行sql优化(即sql语法union all代替or可以提高效率)
- 通过分析SQL语句的执行计划优化SQL (五)
- 通过分析SQL语句的执行计划优化SQL (四)
- Oracle sql 性能优化调整
- [转]通过分析SQL语句的执行计划优化SQL (七)[3]
- [转]通过分析SQL语句的执行计划优化SQL (七)[1]
- [转]通过分析SQL语句的执行计划优化SQL (七)[2]
- LINQ体验(8)——LINQ to SQL语句之Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods
- Oracle sql 性能优化调整
- 通过分析SQL语句的执行计划优化SQL
- [转]通过分析SQL语句的执行计划优化SQL (七)[5]
- SQL指南 - UNION and UNION ALL