优化更新语句中的标量子查询
数据库环境: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
优化更新语句中的标量子查询相关推荐
- 优化案例2:select标量子查询且主查询排序
优化案例2:select标量子查询且主查询排序 1. 场景描述 2. 分析过程 2.1 查看原始SQL执行计划 2.2 ET定位耗时操作符 2.3 注释大法 3. 解决方法 3.1 HINT功法 3. ...
- SQL语句中的嵌套子查询
文章目录 相关子查询 自身连接 一开始在学习的SQL语句的时候,没有感受到嵌套子查询的厉害,尤其是相关子查询.现在发现它的厉害之处,写下来记录! 相关子查询 先抛出一个问题来引出这个话题.查找每个学生 ...
- 标量子查询产生的SQL性能瓶颈,该怎么合理优化?
来自:DBAplus社群 作者介绍 郝昊喆,新炬网络数据库专家.擅长数据库方面的开发.整体架构及复杂SQL的调优,参与了多个行业核心系统的优化工作,目前专注于对开源技术.自动化运维和性能调优技术的研究 ...
- 性能为王:SQL标量子查询的优化案例分析
本篇整理内容是黄廷忠在"云和恩墨大讲堂"微信分享中的讲解案例,SQL优化及SQL审核,是从源头解决性能问题的根本手段,无论是开发人员还是DBA,都应当持续深入的学习SQL开发技能, ...
- 12C 新特性 | 标量子查询自动转换
有超过6年超大型数据库专业服务经验,擅长数据库解决方案设计与项目管理:在多年的技术实践中,先后为运营商(移动.电信).银行.保险.制造业等各行业客户的业务关键型系统提供了运维.升级.性能优化.项目实施 ...
- order by 子查询_视图,子查询,标量子查询,关联子查询
视图 子查询 标量子查询 关联子查询 如何用SQL解决业务问题 各种函数 1. 视图 视图内存放SQL查询语句,运行时运行该语句.查出的数据为临时数据 创建视图 create view as 视图名称 ...
- sql 标量子查询_SQL Server 2017:标量子查询简化
sql 标量子查询 Nowadays a lot of developers use Object-Relational Mapping (ORM) frameworks. ORM is a prog ...
- [20180602]函数与标量子查询3.txt
[20180602]函数与标量子查询3.txt --//前面看http://www.cnblogs.com/kerrycode/p/9099507.html链接,里面提到: 通俗来将,当使用标量子查询 ...
- SELECT中常用的子查询操作
MySQL中的子查询 是在MySQL中经常使用到的一个操作,不仅仅是用在DQL语句中,在DDL语句.DML语句中也都会常用到子查询. 子查询的定义: 子查询是将一个查询语句嵌套在另一个查询语句中: 在 ...
最新文章
- 实现Web虚拟现实的最轻松方案—A-Frame框架
- scp错误 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
- Spring Boot整合Spring Data Redis-存取JSON格式Java对象
- [转载]用消息队列和消息应用状态表来消除分布式事务
- java识别音调_你如何创建一个音调发生器,其音调可以在java中“实时”或动态地操作?...
- 使用spring-data-jpa实现简单的两表联查
- Android 系统(232)---减小 OTA 大小
- js 将内部函数变成全局函数_js中三种作用域详解(全局,函数,块级)
- hdu3949(线性基,求第k小的异或和
- 鼠标点击层以外的地方层隐藏
- 求合作开发伙伴 .NET 中高级工程师 1-2名
- CSS学习总结(2)——选择器
- 单片机基础:MCS-51单片机的硬件结构(附硬件结构框图)
- html 小喇叭图标,小喇叭不见了怎么办(小喇叭图标不见了的原因及解决办法)...
- 电子工程师英年早秃?离高阶茂密工程师你只差这套工具!
- 《搞不定人,你如何带团队?》读书记录
- 创建单链表的头插法与尾插法详解
- js逆向爬虫某openLaw网站
- mysql如何查询成绩前5名_sql 语句查询 前5名后5名的成绩
- pomelo架构概览
热门文章
- 如何构建NLP Pipeline,各模块代码实现细节全在这里!
- 2018蚂蚁金服NLP用户意图的精准识别,复赛f1 = 0.7327
- 大神总结的机器学习的数学基础,掌握这些足够
- vue 两个table 并排_从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(六)
- linux 系统lv扩展_Filecoin 运维(1) 几个常用的系统配置
- 被踢出sci_这本世界上创刊最早的期刊竟被踢出 SCI 了?!
- linux standby模式,搭建11g 单机 linux standby 操作文档
- java怎么限制一个对象的内存_java对象的内存布局及创建过程
- 某大型银行深化系统之十八:性能设计之三
- Android基站定位——单基站定位(二)