ORACLE应用调优:请避免SQL做大量循环逻辑处理
前阵子遇到一个案例:一个同事说以前一个运行很正常的包,突然间比以前慢了很多,执行时间非常长,晚上的作业调用这个包跑了几个小时也没有跑出数据。于是我在跟踪、优化过程中定位到包中一个存储过程的一段SQL,我将原SQL简化了一下(对应的表名、函数全都随机取名替换掉),大体如下所示,在一个游标中,循环更新表TMP_JO_ORDERS, 其中需要通过函数获取一些值,这些值用来更新目标表的字段值
FOR CUR_JO IN (SELECT JOB_ORDER_NO FROM TMP_JO_ORDERS WHERE SEW_START >=SYSDATE ) LOOP
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'SEWING','BUTTON') INTO MY_M_BUTTON FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'SEWING','LABEL') INTO MY_M_LABEL FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'SEWING','TAPE') INTO MY_M_TAPE FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'SEWING','ZIPPER') INTO MY_M_ZIPPER FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'SEWING','OTHERS') INTO MY_M_OTHERS FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'THREAD','ALL') INTO MY_M_THREAD FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'INTERLINING','ALL') INTO MY_M_INTERLINING FROM DUAL;
SELECT MAIN_ITC.GET_MUST_INFO(CUR_JO.JOB_ORDER_NO,'PACKING','ALL') INTO MY_M_PACKING FROM DUAL;
UPDATE TMP_JO_ORDERS A
SET M_BUTTON=MY_M_BUTTON
,M_LABEL=MY_M_LABEL
,M_TAPE=MY_M_TAPE
,M_ZIPPER=MY_M_ZIPPER
,M_OTHERS=MY_M_OTHERS
,M_THREAD=MY_M_THREAD
,M_INTERLINING=MY_M_INTERLINING
,M_PACKING=MY_M_PACKING
WHERE JOB_ORDER_NO=CUR_JO.JOB_ORDER_NO;
END LOOP;
其实以前运行正常,突然出现性能问题,是因为SELECT JOB_ORDER_NO FROM TMP_JO_ORDERS WHERE SEW_START >=SYSDATE的数据量由于业务量突然增加了很多,所以游标的循环次数从以前几十次突然飚增到8千多次。
假设游标里面的SQL执行时间需要2秒,以前只循环了30次,那么运算该SQL需要2*30=60秒,如果循环次数突然飚增到8000次,2*8000=16000秒,这就是几个小时的时间。你可以想象一下,这个性能会突然下降到一种无法忍受的程度!
那么怎么优化呢? 当然是减少循环次数。仔细观察了这段SQL,弄明白写这个SQL的老兄的业务逻辑后,上面的循环处理完全可以用下面一个SQL语句替换,完全没有必要一条记录一条记录更新。当时修改后测试,发现修改后的SQL,不到1分钟就运行出来了。
UPDATE TMP_JO_ORDERS A
SET M_BUTTON =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'SEWING','BUTTON')
,M_LABEL =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'SEWING','LABEL')
,M_TAPE =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'SEWING','TAPE')
,M_ZIPPER =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'SEWING','ZIPPER')
,M_OTHERS =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'SEWING','OTHERS')
,M_THREAD =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'THREAD','ALL')
,M_INTERLINING=MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'INTERLINING','ALL')
,M_PACKING =MAIN_INTERFACE.GET_MUST_INFO(JOB_ORDER_NO,'PACKING','ALL')
WHERE SEW_START >=SYSDATE;
其实这只是一个特殊的案例,我只是将其当做一个引子,引入我想阐述的观点:我们知道SQL是结构化查询语言,擅长于结构化查询,而不擅长于逻辑处理(WHIE、IF..ELSE),但是有时候,很多人喜欢用SQL来处理业务逻辑,当然也不是说不能在存储过程、函数里面做一些业务逻辑处理,只是发现不少人过度放大SQL的逻辑处理功能,将复杂的逻辑运算全部搬到包、存储过程里面处理,例如上面的循环运算,这样做的一个糟糕结果就是性能问题,就好像一个擅长于短跑的人,你硬要他去参加长跑。那么比赛结果肯定不会好到哪里去。
在开发中,我们要对业务逻辑做一些优化处理,避免复杂的逻辑运算,尤其避免循环次数非常大的业务逻辑处理,一方面我们要简化业务逻辑,有些业务逻辑运算转到程序中去处理,另外一方面我们可以用SQL很巧妙的实现很多逻辑复杂的需求,避免我们去做大量复杂的逻辑处理,而不要在复杂的业务下写出更加复杂的SQL语句.例如上面的例子,我以前在一篇文章MS SQL 挑战问题也述说了这样一种观念。
ORACLE应用调优:请避免SQL做大量循环逻辑处理的更多相关文章
- OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- 初次使用SQL调优建议工具--SQL Tuning Advisor
在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning Advisor :STA),它是新的DBMS_SQLTUNE包. 使用STA一定要保证优化器是CBO模式下 ...
- 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL
周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...
- advisor调优工具优化sql(基于sql_id)
advisor调优工具优化sql(基于sql_id) 问题背景:客户反馈数据库迁移后cpu负载激增,帮忙查看原因 解决思路:1> 查看问题系统发现有大量的latch: cache buffers ...
- Oracle性能调优之物化视图用法简介
目录 一.物化视图简介 二.实践:创建物化视图 一.物化视图简介 物化视图分类 物化视图分类,物化视图语法和as后面的sql分为: (1) 基于主键的物化视图(主键物化视图) (2)基于Rowid的物 ...
- 记一次SQL调优/优化(SQL tuning)——性能大幅提升千倍以上
好久不写东西了,一直忙于各种杂事儿,恰巧昨天有个用户研发问到我一个SQL调优的问题,说性能太差,希望我能给调优下,最近有些懒,可能和最近太忙有关系,本来打算问问现在的情况,如果差不多就不调了,那哥们儿 ...
- Oracle SQL调优系列之SQL Monitor Report
@ 目录 1.SQL Monitor简介 2.捕捉sql的前提 3.SQL Monitor 参数设置 4.SQL Monitor Report 4.1.SQL_ID获取 4.2.Text文本格式 4. ...
- 一个InnoDB性能超过Oracle的调优Case
年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试,本想把MySQL调优到接近Oracle的性能即可,但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助(排名不分先后 ...
- [转]oracle性能调优之--Oracle 10g AWR 配置
一.ASH和AWR的故事 1.1 关于ASH 我们都知道,用户在ORACLE数据库中执行操作时,必然要创建相应的连接和会话,其中,所有当前的会话信息都保存在动态性能视图V$SESSION中,通过该视图 ...
随机推荐
- IE 11 如何设置“用户代理字符串”
"用户代理字符串"这个术语在IE11 之前被叫作“浏览器模式”(Browser Mode),在IE11下面这个特殊的选项被放在F12的“仿真”选项下面了. Figure 1通过按下 ...
- dapper-dot-net用法及其扩展系列
dapper-dot-net用法及其扩展系列 虽然已经一段时间没写.net了,但是昨天看了下dapper和Dapper-Extensions在github仍然有更新,他们的受欢迎程度可想而知.所以想把 ...
- Oracle数据库全球化
一.自定义数据库和各个会话的语言相关行为 1.1 全球化功能 1.2 使用全球化支持功能 二.使用数据库和NLS字符集 2.1 语言排序与选择 2.2 Locale Builder 2.3 使用时区 ...
- js实现可拖拽的div
前言 下午忙里偷闲想写一个可拖拽的例子,留在脑海里一直都是三个事件mouseDown,mouseUp,mouseMove, 但从没有动手实践过,今天想起了自己实践了并学习了张鑫旭的demo实现. 学习 ...
- Scala 中下划线的用途
转载自:https://my.oschina.net/leejun2005/blog/405305 Scala 作为一门函数式编程语言,对习惯了指令式编程语言的同学来说,会不大习惯,这里除了思维方式之 ...
- 在Visual Studio 2012中使用VMSDK开发领域特定语言(二)
本文为<在Visual Studio 2012中使用VMSDK开发领域特定语言>专题文章的第二部分,在这部分内容中,将以实际应用为例,介绍开发DSL的主要步骤,包括设计.定制.调试.发布以 ...
- VARCHAR列上的索引
一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列.我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制. 假设现在你想捉弄 ...
- 让我们一起用开源数据库和开源框架废弃Access
一.为什么要废弃Access? 1.客户的机子上需要安装access的驱动 ps:这个比较烦人,大家都知道部署越简单越好,安装这个对用户来说太繁琐了. 2.操作时性能不佳 using System; ...
- .NET 扩展方法 (二)
上一篇随笔 .NET 扩展方法 (一) 已经对 扩展方法有了大致的介绍,这篇算是一个补充,让我们来看一下扩展方法的几个细节: 一.扩展方法具有继承性 当使用扩展方法扩展一个类型的时候,其也扩展了派生类 ...
- using 的三种用法
using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...