通过调整表union all的顺序优化SQL

简介: 原文:通过调整表union all的顺序优化SQL  操作系统:Windows XP   数据库版本:SQL Server 2005   今天遇到一个SQL,过滤条件是自动生成的,因此,没法通过调整SQL的谓词达到优化的目的,只能去找SQL中的“大表”。
原文: 通过调整表union all的顺序优化SQL

  操作系统: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出结果。

 

目录
相关文章
|
21天前
|
SQL 存储 关系型数据库
一文搞懂SQL优化——如何高效添加数据
**SQL优化关键点:** 1. **批量插入**提高效率,一次性建议不超过500条。 2. **手动事务**减少开销,多条插入语句用一个事务。 3. **主键顺序插入**避免页分裂,提升性能。 4. **使用`LOAD DATA INFILE`**大批量导入快速。 5. **避免主键乱序**,减少不必要的磁盘操作。 6. **选择合适主键类型**,避免UUID或长主键导致的性能问题。 7. **避免主键修改**,保持索引稳定。 这些技巧能优化数据库操作,提升系统性能。
215 4
一文搞懂SQL优化——如何高效添加数据
|
1月前
|
SQL 存储 数据库连接
日活3kw下,如何应对实际业务场景中SQL过慢的优化挑战?
在面试中,SQL调优是一个常见的问题,通过这个问题可以考察应聘者对于提升SQL性能的理解和掌握程度。通常来说,SQL调优需要按照以下步骤展开。
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
99 1
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
163 0
|
22天前
|
SQL 关系型数据库 MySQL
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
【MySQL技术之旅】(7)总结和盘点优化方案系列之常用SQL的优化
36 1
|
23天前
|
SQL 索引
SQL怎么优化
SQL怎么优化
30 2
|
1月前
|
SQL 监控 测试技术
SQL语法优化与最佳实践
【2月更文挑战第28天】本章将深入探讨SQL语法优化的重要性以及具体的优化策略和最佳实践。通过掌握和理解这些优化技巧,读者将能够编写出更高效、更稳定的SQL查询,提升数据库性能,降低系统资源消耗。
|
1月前
|
SQL 关系型数据库 MySQL
[MySQL]SQL优化之sql语句优化
[MySQL]SQL优化之sql语句优化
|
1月前
|
SQL 关系型数据库 MySQL
[MySQL]SQL优化之索引的使用规则
[MySQL]SQL优化之索引的使用规则
|
1月前
|
SQL 存储 关系型数据库
[MySQL] SQL优化之性能分析
[MySQL] SQL优化之性能分析