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

通过调整表union all的顺序优化SQL的更多相关文章

  1. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  2. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  3. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

  4. MySQL查询不使用索引汇总 + 如何优化sql语句

    不使用索引原文 : http://itlab.idcquan.com/linux/MYSQL/918330.html MySQL查询不使用索引汇总 众所周知,增加索引是提高查询速度的有效途径,但是很多 ...

  5. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  6. mysql优化sql语句

    mysql优化sql语句   常见误区   www.2cto.com   误区1:   count(1)和count(primary_key) 优于 count(*)   很多人为了统计记录条数,就使 ...

  7. 数据库优化 - SQL优化

    前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优.但是一些"不好"的SQL也会导致数据库查询变慢,影响业务流程.本文从SQL角度进行数据库优化,提升SQ ...

  8. 转载 数据库优化 - SQL优化

    判断问题SQL判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象CPU消耗严重IO等待严重页面响应时间过长应用的日志出现超时等错误可以使用sar命令,top命令查看当前系统状态. 也可以通 ...

  9. MySql(五)SQL优化-优化SQL语句的一般步骤

    MySql(五)SQL优化-优化SQL语句的一般步骤 一.优化SQL语句的一般步骤 1.1 通过show status命令了解各种SQL的执行频率 1.2 定位执行效率较低的SQL语句 1.3 通过e ...

随机推荐

  1. Net中的反射使用入门

    [转载] MSDN:ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondiscoveringtypeinformatio ...

  2. Method Overloading in WCF zt

    Method overloading is the process of implementing Polymorphism in Object-Oriented Programming. A met ...

  3. 【转】QTP书写程序技巧

    一.添加固定注释 新建一TXT文档,将要添加的注释写在文档中 将文档名改为:ActionTemplate.mst 将文件放到QTP安装目录的dat文件夹中 设置好后,在QTP中每次新建一个测试就会自动 ...

  4. python 零散记录(四) 强调字典中的键值唯一性 字典的一些常用方法

    dict中键只有在值和类型完全相同的时候才视为一个键: mydict = {1:1,':1} #此时mydict[1] 与 mydict['1']是两个不同的键值 dict的一些常用方法: clear ...

  5. hdoj 2036 改革春风吹满地

    改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  6. SpringMVC 流程 配置 接口

    SpringMVC简介    一 流程介绍 1.角色划分 前端控制器(DispatcherServlet).请求到处理器映射(HandlerMapping).处理器适配器(HandlerAdapter ...

  7. 【bzoj3172】 [Tjoi2013]单词

    题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...

  8. php获取机器网卡的物理(MAC)地址

    <?php /** 获取网卡的MAC地址原码:目前支持WIN/LINUX系统 获取机器网卡的物理(MAC)地址 **/ class GetMacAddr{ var $return_array = ...

  9. ASP.NET MVC- Controllers and Routing- Routing

    二.Creating Custom Routes In this tutorial, you learn how to  add a custom route to an ASP.NET MVC ap ...

  10. servlet中避免405错误的产生

    父类Parent(相当于HttpServlet):service方法,用于处理任务分发,doGet.doPost方法用于报错  关注的是子类Son(servlet)     目的:杜绝错误的产生 方式 ...