操作系统: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. Android4.0 -- UI控件之 Menu 菜单的的使用(二)

    上一讲我们讲解了android中在代码或者xml文件中定义菜单,这一讲我们继续来讲解一下定义菜单的其他方式:创建上下文的菜单.查看API文档 Menus :Creating Contextual Me ...

  2. 排序算法_HeapSort

    大根堆排序的基本思想: 1) 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区; 2) 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,    由此得到新的无序区 ...

  3. [SDOI2015]权值

    问题描述: 有一个长度为n的实数序列,,下标从1开始,其中第k个位置的实数为p · (sin(a · k + b) + cos(c · k + d) + 2),sin和cos采用弧度制,其中p,a,b ...

  4. [CODEVS1014]装箱问题

    题目描述 Description 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若 ...

  5. Keepass 2.x 之 同步与触发器

    同步 之前用的 Keepass 1.x, 要实现工作电脑和个人电脑上的数据库文件同步,使用的是第三方的网盘同步.但有个问题就是,个人不习惯设置同步网盘开机启动,所以有时候工作电脑上的改动还没有同步上传 ...

  6. JavaScript高级程序设计41.pdf

    事件对象 在触发DOM上某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息. DOM中的事件对象 兼容DOM的浏览器会将event对象传入到事件处理程序中,无论指定事件处理 ...

  7. usaco 地震 && 奶牛观光

    Usaco 地震: Description 一场地震把约翰家的牧场摧毁了,坚强的约翰决心重建家园.约翰已经重建了N个牧场, 现在他希望能修建一些道路把它们连接起来.研究地形之后,约翰发现可供修建的道路 ...

  8. Python默认编码错误SyntaxError: Non-ASCII character '\xe5'之解决方法

    在编写Python时,当使用中文输出或注释时运行脚本,会提示错误信息: SyntaxError: Non-ASCII character '\xe5' in file ******* 解决方法: py ...

  9. Linux中如何新建用户

    对于一般用户来说,主目录(home directory)是硬盘上唯一可以原来写东西的地方.一般的路径名是/home/login_user_name. 主目录用于存储各种用户文件:设置文件,程序配置文件 ...

  10. Android中实现控件圆角边框

    首先,在drawable文件夹下新建一个xml文件: <?xml version="1.0" encoding="utf-8"?> <shap ...