数据库环境:SQL SERVER 2008R2

今天看到开发写的一条更新语句,第一眼是觉得这个SQL的业务有问题,再细看子查询部分,才意识到这是开发人员使的“怪招”。

这个SQL能满足业务的需要,只是开发人员在写这个SQL的时候应该不会考虑到存在性能问题。具体SQL如下:

UPDATE  fapply_04
SET     conf_y_fee_amt = ISNULL(conf_y_fee_amt, 0)+ ISNULL(( SELECT   SUM(fexp_03.opr_amt)FROM     fexp_03WHERE    fexp_03.com_id = fapply_04.com_idAND fexp_03.origin_no = fapply_04.fapply_noAND fexp_03.origin_line_no = fapply_04.line_noAND fexp_03.feetype_flag = ''AND fexp_03.fexp_no = :fexp_no), 0)

开发人员原本想把fexp_03表中的opr_amt累加到对应记录的fapply_04表的conf_y_fee_amt字段上,但是,这条SQL实际上

把fapply_04整张表都更新了(没有对应记录则累加0)。

现在我们来做个实验,验证一下我的说法

1.数据准备

创建2张表,分别是表a和表b,脚本脚本如下:

--创建a表
SELECT * INTO a FROM
(
SELECT 1 AS id,10 AS score
UNION ALL
SELECT 2 AS id,20 AS score
UNION ALL
SELECT 3 AS id,30 AS score
UNION ALL
SELECT 4 AS id,40 AS score) t
--创建b表
SELECT * INTO b FROM(
SELECT 2 AS id,-20 AS cn) t

2.更新数据

如果a表和b表的id匹配,则累加b表对应的cn字段的数据,否则,减5。

UPDATE  a
SET     score = score + ISNULL(( SELECT cnFROM   bWHERE  b.id = a.id), -5)
SELECT  *
FROM    a

好,我们现在来对比一下更新前后,a表数据的变化。左图是更新前,右图是更新后。

     

看到没,是不是a表发生了全表更新呢?

全表更新把不必要的记录也更新了,数据量大的时候,会造成不必要的影响。

那怎么避免这个问题呢?

把子查询改成内连接即可,看脚本

UPDATE  a
SET     a.score = a.score + b.cn
FROM    aINNER JOIN b ON a.id = b.id
SELECT  *
FROM    a

再贴上结果图,对比前面的子查询更新的图,是不是用内连接只更新了条件匹配的记录?

现在我们回到开始的案例,我把更新语句改成查询的了,然后执行。总共查询出476056条记录,耗时30s。

SELECT  conf_y_fee_amt = ISNULL(conf_y_fee_amt, 0)+ ISNULL(( SELECT   SUM(fexp_03.opr_amt)FROM     fexp_03WHERE    fexp_03.com_id = fapply_04.com_idAND fexp_03.origin_no = fapply_04.fapply_noAND fexp_03.origin_line_no = fapply_04.line_noAND fexp_03.feetype_flag = ''AND fexp_03.fexp_no = '200710000335'), 0)
FROM    fapply_04
/*分别统计fapply_04,fexp_03的数据*/
SELECT  COUNT(*)
FROM    fexp_03
WHERE   fexp_03.feetype_flag = ''AND fexp_03.fexp_no = '200710000335'--3
SELECT  COUNT(*)
FROM    fapply_04--476056

然后,把SQL改写成内联接的方式,我们再来看一下执行情况。查询1条数据,耗时0s。

SELECT  conf_y_fee_amt = ISNULL(fapply_04.conf_y_fee_amt, 0)+ ISNULL(fexp_03.opr_amt, 0)
FROM    fapply_04INNER JOIN ( SELECT com_id ,origin_no ,origin_line_no ,SUM(fexp_03.opr_amt) opr_amtFROM   fexp_03WHERE  fexp_03.feetype_flag = ''AND fexp_03.fexp_no = '200710000335'GROUP BY com_id ,origin_no ,origin_line_no) fexp_03 ON fexp_03.com_id = fapply_04.com_idAND fexp_03.origin_no = fapply_04.fapply_noAND fexp_03.origin_line_no = fapply_04.line_no
/*分别统计fapply_04,fexp_03的数据*/
SELECT  COUNT(*)
FROM    fexp_03
WHERE   fexp_03.feetype_flag = ''AND fexp_03.fexp_no = '200710000335'--3SELECT  COUNT(*)
FROM    fapply_04--476056

综上,根据业务的意思,原本只需更新一条记录的,由于使用子查询,做了全表更新。

小结一下,有些时候,我们光是把SQL实现了还不够,还要考虑我们的代码会不会造成性能问题,再多想想可能的实现方法。

(本文完)

转载于:https://www.cnblogs.com/boss-he/p/4547425.html

优化更新语句中的标量子查询相关推荐

  1. 优化案例2:select标量子查询且主查询排序

    优化案例2:select标量子查询且主查询排序 1. 场景描述 2. 分析过程 2.1 查看原始SQL执行计划 2.2 ET定位耗时操作符 2.3 注释大法 3. 解决方法 3.1 HINT功法 3. ...

  2. SQL语句中的嵌套子查询

    文章目录 相关子查询 自身连接 一开始在学习的SQL语句的时候,没有感受到嵌套子查询的厉害,尤其是相关子查询.现在发现它的厉害之处,写下来记录! 相关子查询 先抛出一个问题来引出这个话题.查找每个学生 ...

  3. 标量子查询产生的SQL性能瓶颈,该怎么合理优化?

    来自:DBAplus社群 作者介绍 郝昊喆,新炬网络数据库专家.擅长数据库方面的开发.整体架构及复杂SQL的调优,参与了多个行业核心系统的优化工作,目前专注于对开源技术.自动化运维和性能调优技术的研究 ...

  4. 性能为王:SQL标量子查询的优化案例分析

    本篇整理内容是黄廷忠在"云和恩墨大讲堂"微信分享中的讲解案例,SQL优化及SQL审核,是从源头解决性能问题的根本手段,无论是开发人员还是DBA,都应当持续深入的学习SQL开发技能, ...

  5. 12C 新特性 | 标量子查询自动转换

    有超过6年超大型数据库专业服务经验,擅长数据库解决方案设计与项目管理:在多年的技术实践中,先后为运营商(移动.电信).银行.保险.制造业等各行业客户的业务关键型系统提供了运维.升级.性能优化.项目实施 ...

  6. order by 子查询_视图,子查询,标量子查询,关联子查询

    视图 子查询 标量子查询 关联子查询 如何用SQL解决业务问题 各种函数 1. 视图 视图内存放SQL查询语句,运行时运行该语句.查出的数据为临时数据 创建视图 create view as 视图名称 ...

  7. sql 标量子查询_SQL Server 2017:标量子查询简化

    sql 标量子查询 Nowadays a lot of developers use Object-Relational Mapping (ORM) frameworks. ORM is a prog ...

  8. [20180602]函数与标量子查询3.txt

    [20180602]函数与标量子查询3.txt --//前面看http://www.cnblogs.com/kerrycode/p/9099507.html链接,里面提到: 通俗来将,当使用标量子查询 ...

  9. SELECT中常用的子查询操作

    MySQL中的子查询 是在MySQL中经常使用到的一个操作,不仅仅是用在DQL语句中,在DDL语句.DML语句中也都会常用到子查询. 子查询的定义: 子查询是将一个查询语句嵌套在另一个查询语句中: 在 ...

最新文章

  1. 实现Web虚拟现实的最轻松方案—A-Frame框架
  2. scp错误 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
  3. Spring Boot整合Spring Data Redis-存取JSON格式Java对象
  4. [转载]用消息队列和消息应用状态表来消除分布式事务
  5. java识别音调_你如何创建一个音调发生器,其音调可以在java中“实时”或动态地操作?...
  6. 使用spring-data-jpa实现简单的两表联查
  7. Android 系统(232)---减小 OTA 大小
  8. js 将内部函数变成全局函数_js中三种作用域详解(全局,函数,块级)
  9. hdu3949(线性基,求第k小的异或和
  10. 鼠标点击层以外的地方层隐藏
  11. 求合作开发伙伴 .NET 中高级工程师 1-2名
  12. CSS学习总结(2)——选择器
  13. 单片机基础:MCS-51单片机的硬件结构(附硬件结构框图)
  14. html 小喇叭图标,小喇叭不见了怎么办(小喇叭图标不见了的原因及解决办法)...
  15. 电子工程师英年早秃?离高阶茂密工程师你只差这套工具!
  16. 《搞不定人,你如何带团队?》读书记录
  17. 创建单链表的头插法与尾插法详解
  18. js逆向爬虫某openLaw网站
  19. mysql如何查询成绩前5名_sql 语句查询 前5名后5名的成绩
  20. pomelo架构概览

热门文章

  1. 如何构建NLP Pipeline,各模块代码实现细节全在这里!
  2. 2018蚂蚁金服NLP用户意图的精准识别,复赛f1 = 0.7327
  3. 大神总结的机器学习的数学基础,掌握这些足够
  4. vue 两个table 并排_从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(六)
  5. linux 系统lv扩展_Filecoin 运维(1) 几个常用的系统配置
  6. 被踢出sci_这本世界上创刊最早的期刊竟被踢出 SCI 了?!
  7. linux standby模式,搭建11g 单机 linux standby 操作文档
  8. java怎么限制一个对象的内存_java对象的内存布局及创建过程
  9. 某大型银行深化系统之十八:性能设计之三
  10. Android基站定位——单基站定位(二)