分享一个sql优化案例case

问题提出:某一应用db服务器迁移到idc后,总部基础资料同步到这台db上整个同步耗时在4个小时以上,用户难以接受,观察到这个现象后,即着手对同步基础资料的存储过程做优化调整下面的调整优化以同步中的某一个大表ka_detail为例,列出优化的步骤和方法,最终的调整结果:过程执行时间由2个小时以上,优化为现在的30秒左右。

记录文档,供参考。

检查同步过程,发现因业务系统的限制,同步时间主要消耗在本地table和通过dblink的远程table的delete,update,insert上,此外远程table上有trigger,也是一个因素;整个同步时间耗时过长,和数据仓库db每天的停机冷备份冲突,最终可能会导致基础资料还没有同步结束的时候,数据仓库db停机做冷备份,进而导致同步过程失败,影响下游系统的作业。

一:查看当前状况下同步ka单店过程执行的时间

14:10:44 SQL> exec syn_fenxiao_ka_detail;

start syn_fenxiao_ka_detail time0 is:20071219 14:14:09

start syn_fenxiao_ka_detail time1 is:20071219 14:14:11

insert and update of ka_detail synchronize is unsuccessful!!!-0008-SUG0632

begin syn_fenxiao_ka_detail_before; end;

ORA-01013: user requested cancel of current operation

16:38:34 SQL>


同步过程exec syn_fenxiao_ka_detail 执行了2个多小时还没有完成,手工停止。


:第一次优化过程,用merge语句代替insert,update 语句

查看ka_detail 表的记录数

SQL> select count(*) from ka_detail;

 COUNT(*)

----------

    11822

该表有近12000笔记录,为基础资料中最大的一个表。分析同步该表的过程syn_fenxiao_ka_detail ,过程中的update和insert语句可以用merge 语句代替,只需要一次全表扫描,将会较大程度的提高过程的执行效果(oracle 9i 新增的merge 语句,对于数据仓库中经常用的数据批量导入更新,可以较好的提高sql语句的效率),过程修改后的执行情况如下

10:48:53 SQL> exec syn_fenxiao_ka_detail;

start syn_fenxiao_ka_detail time0 is:20071219 10:52:23

start syn_fenxiao_ka_detail time1 is:20071219 11:29:48

start syn_fenxiao_ka_detail time2 is:20071219 11:29:55

start syn_fenxiao_ka_detail time2 is:20071219 11:29:55

syn_fenxiao_ka_detail synchronize successful!!!

可以看到,第一次优化后的执行时间将在40分钟左右,过程的执行效果有了很大提高


三:第二次优化过程

再次分析过程syn_fenxiao_ka_detail,对程序进行分段测试,确定40分钟的耗时在每个子程序段的分布情况(可以采用分段测试,增加dbms_output.put_line,来确定过程执行的瓶颈正在那个子程序段上,或者利用操作系统的topas/top,结合v$session,v$process,v$sqltext ,可以确定耗用资源最多的,占用时间最长的sql语句,对此语句进行优化)。

start syn_fenxiao_ka_detail time0 is:20071219 10:52:23

start syn_fenxiao_ka_detail time1 is:20071219 11:29:48

观察上面的测试输出,找到对应的程序段,可以发现执行时间绝大部分为delete语句。

找到对应的语句,分析该语句的执行计划和统计信息,如下

SQL> delete ka_detail@lfxpub a where not Exists

 2  (select 'x' from ka_detail b where a.ka_detail=b.ka_detail);

已删除0行。

统计信息

----------------------------------------------------------

     23628 recursive calls

         0 db block gets

     23624 consistent gets

         0 physical reads

         0 redo size

       518 bytes sent via SQL*Net to client

       394 bytes received via SQL*Net from client

         4 SQL*Net roundtrips to/from client

         1 sorts (memory)

         0 sorts (disk)

         0 rows processed


consisten read 非常大,这么大的逻辑读是造成同步耗时的主要原因,应考虑优化(需要参考sql的执行计划)。最终优化后的语句的执行计划和统计信息如下

SQL> delete ka_detail@lfxpub where ka_detail in

 2 (

 3 select ka_detail from ka_detail@lfxpub

 4 minus

 5 select ka_detail from ka_detail

 6 );

已删除0行。

统计信息

----------------------------------------------------------

         6 recursive calls

         0 db block gets

        93 consistent gets

         0 physical reads

         0 redo size

       532 bytes sent via SQL*Net to client

       414 bytes received via SQL*Net from client

         4 SQL*Net roundtrips to/from client

         1 sorts (memory)

         0 sorts (disk)

         0 rows processed

可以看到,优化后sql的consisten read 降低了大概200倍,效率有了极大提高。

至此,表ka_detail的同步过程优化结束,其他过程,亦可参照处理。

SQL> set serveroutput on;

SQL> set time on;

14:24:59 SQL> exec syn_pesd_ka_detail;

insert and update of ka_detail synchronize successful!!!


PL/SQL procedure successfully completed

14:25:31 SQL>

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
搜索
标签列表
网站分类
最新留言
    文章归档
    友情链接

    Powered By Z-BlogPHP 1.7.3

    Copyright Your WebSite.Some Rights Reserved.闽ICP备11018667号-2