`
lxf3339
  • 浏览: 59565 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

pl/sql存储过程优化一例

阅读更多

问题提出:

etl中有一过程qmsressummt0_test,用来抽取各地xxx应用的资料,目前处于测试阶段,暂时存放2个厂区一个月的测试资料,目前该过程执行一次要30分钟,按此状况,日后如再抽取其他厂区的资料,预计执行三个小时以上,小组开发人员请求协助优化。

 

优化前的执行情况

9:31:20 SQL> set serveroutput on;

9:31:25 SQL> exec qmsressummt0_test;

 

PL/SQL procedure successfully completed

10:00:54 SQL>

执行一次,耗时在30分钟

调优步骤:

步骤一:调整sql的优化器由rbo变为采用cbo方式

 

查看procedure涉及到table的统计信息三个表都没有统计信息

10:33:35 SQL> select * from user_tables where table_name in ('QMS310T0','QMS311T0',UPPER('qmsressummt0'));

 

TABLE_NAME     TABLESPACE_NAME   NUM_ROWS    BLOCKS EMPTY_BLOCKS AVG_SPACE

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

QMS310T0                      QMSS                                                          

QMS311T0                      QMSS                                                          

QMSRESSUMMT0                  QMSS     

 

Oracle9i10gsql优化器优先采用cbo方式,cbo方式下,oracle优化器可以更智能更合理的选择执行计划,从而使sql的执行效率更高,而若相关tableindex没有统计信息的话,则会转而采用传统的rbo方式,在此例子中,任意查看过程中的某个sql,发现都是采用rbo

 

接下来分析该过程涉及到的三个表,收集相关统计信息。

 

对这三个表做分析,收集统计信息

 

10:00:54 SQL> analyze table qms310t0 compute statistics for table for all indexes;

Table analyzed

10:33:11 SQL> analyze table qms311t0 compute statistics for table for all indexes;

Table analyzed

10:33:21 SQL> analyze table qmsressummt0 compute statistics for table for all indexes;

Table analyzed

10:33:35 SQL>                                                 

 

可以试验比对一下,采用rbocbo的执行效率对比情况

10:41:43 SQL> exec qmsressummt0_test;

PL/SQL procedure successfully completed

11:03:37 SQL>

 

可以发现,现在的执行时间在20分钟,在此过程中,效率提高了接近1/3,由此,我们可以看到相同的sql语句,优化器采用cbo比采用rbo效率要提高不少。

 

步骤二:合理利用索引,进一步提高sql执行效率

 

分析proceduretable,相关的表需要建立索引,这一步需要根据以往的经验,建立相关索引(开发人员并没有考虑新增索引,甚至主键都没有),并抽取sql语句,查看索引添加前后的执行计划,最终建立的索引(主键索引)如下

SQL> alter table QMS310t0

add constraint PK1_QMS310T0 primary key (BRANCH_NO, CHECK_NO,vend_id,mtrl_no)

Using Index tablespace indx;

Table altered

SQL> alter table QMS311t0

    add constraint PK1_QMS311T0 primary key (BRANCH_NO, CHECK_NO, SAMPL_NO,mtrl_no, CHK_NO)

    Using Index tablespace indx ;

Table altered

 

SQL>alter table qmsressummt0 add constraint pk_qmsresssummt0 primary key (yyyymm,branch_no,vend_id,mtrl_no,chk_no) using index tablespace indx;

Table altered

 

SQL> create index idx_qms310t0_ymd on qms310t0(yymmdd) tablespace indx;

Index created

 

 

 

再次执行过程

11:43:51 SQL> exec qmsressummt0_test;

PL/SQL procedure successfully completed

11:49:34 SQL>

 

时间大约为6分钟。

 

步骤三:合理的改变业务处理方式,亦可提高程序执行效率

对该过程的深入分析可以发现,其中的max最大值,min最小值,和count(*)三个sql语句可以合并成一个sql语句,这样同样可以达到减少sql的执行次数和数据块的io数量,提高效率和降低执行时间的目的。

 

 

修改前的sql语句                    |        修改后的sql语句

                                    

select max(b.item_val)                   | select max(b.item_val),min(b.item_val),Count(*)                                              
     into v_chk_max                     |       into v_chk_max,v_chk_min,v_cnt_01
     from qms310t0 a, qms311t0 b        |   from qms310t0 a, qms311t0 b
    where a.check_no = b.check_no       |   where a.check_no = b.check_no
      and a.branch_no = b.branch_no     |     and a.branch_no = b.branch_no
      and a.mtrl_no = r1.mtrl_no        |     and a.mtrl_no = r1.mtrl_no
      and a.vend_id = r1.vend_id        |     and a.vend_id = r1.vend_id
      and a.branch_no = r1.branch_no    |     and a.branch_no = r1.branch_no
      and b.chk_no = r1.chk_no;         |     and b.chk_no = r1.chk_no;

                                         |

select min(b.item_val)               |
     into v_chk_min                     |
     from qms310t0 a, qms311t0 b        |
    where a.check_no = b.check_no       |
      and a.branch_no = b.branch_no     |
      and a.mtrl_no = r1.mtrl_no        |
      and a.vend_id = r1.vend_id        |
      and a.branch_no = r1.branch_no    |
      and b.chk_no = r1.chk_no;         |
 
   SELECT count(*)                      |
     INTO v_cnt_01                      |
     FROM qms311t0 a, qms310t0 b        |
    WHERE a.branch_no = r1.branch_no    |
      AND a.mtrl_no = r1.mtrl_no        |
      AND a.chk_no = r1.chk_no          |
      and a.check_no = b.check_no       |
      and a.branch_no = b.branch_no;    |

 

执行的情况:

15:31:13 SQL> exec qmsressummt0_test

PL/SQL procedure successfully completed

15:33:42 SQL>

 

最终,该过程执行的时间<3分钟

 

至此,程序执行效率提高10倍左右,调整优化结束。

分享到:
评论

相关推荐

    PL/SQL学习笔记

    所有的pl/sql都叫过程 创建存储过程: create or replace procedure p1 (v1 int ,v2 int)--存储过程的参数列表 as --声明局部变量 begin null; end; 调用过程 1.declare调用 2.命令调用 删除存储过程:drop ...

    PL/SQL 基础.doc

    PL/SQL 基础,一个不错的 PL/SQL 参考手册。内容预览: ---- 第一章 PL/SQL 简介 ---- 1. Oracle应用编辑方法概览 1) Pro*C/C++/... : C语言和数据库打交道的方法,比OCI更常用; 2) ODBC 3) OCI: C语言和...

    PL/SQL中编写Oracle数据库分页的存储过程

    此文以oracle数据库中的SCOTT用户的EMP表为例,用PL/SQL Developer编写一个分页存储过程,要求是:可以输入表名,每页显示记录数,当前页,返回总记录数,总页数和返回的结果集。 由于需要返回查询出来的结果集,...

    PLSQL开发过程中,动态使用DBMS_SQL[借鉴].pdf

    在 PL/SQL 开发过程中,使用 SQL、PL/SQL 可以实现大部分的需求,但是在某些特殊的情况下,在 PL/SQL 中使用标准的 SQL 语句或 DML 语句不能实现自己的需求,比如需要动态建表或某个不确定的操作需要动态执行。...

    oracle存储过程编译

    在本例中,我们将讨论如何使用 Oracle 存储过程编译,特别是使用 PL/SQL 语言编写的存储过程。 标题:Oracle 存储过程编译 描述:Oracle 存储过程编译 标签:Oracle 部分内容: 在上面的代码中,我们定义了一个...

    PLSQL开发中动态SQL的使用方法.doc

    下面是一个简单的示例,创建一个存储过程,动态执行 DML 语句,插入数据到上例中建好的 dinya_test 表中。 create or replace procedure proc_insert(id in number, name in varchar2) as str_sql varchar2(500...

    OraclePLSQL编程经典例子

    通过在过程中使用输入参数,可以讲数据输入到执行部分,通过使用输出参数,可以将执行部分的数据输出到应用环境,在pl/sql中可以使用create procedure命令来创建过程。 编写一个存储过程,可以输入雇员名和新工资来...

    oracle存储过程应用实例

    Oracle 允许将PL/ SQL 语言编写的存储过程作为数据库对象存储在数据库中,存储过程通过语法分析,将第一 次执行编译的SQL 语句存储在高速缓冲存储器中,下次使用只需从高速缓冲区中调用已编译的代码,加速了SQL 语句的执...

    oracle教案(doc)+SQL Reference 10g(chm).rar

    7.5.7 SQL语句在PL/SQL中的运用 114 7.6 选择结构 114 7.6.1 格式1: IF_THEN_ELSE语句 114 7.6.2 格式2: IF_THEN_ELSE_IF语句 114 7.7 循环结构 114 7.8 异常处理(了解) 114 7.8.1 异常 114 7.8.2 PL/SQL是如何处理...

    软件开发面试题,葵花宝典

    PL/SQL 是一种 procedural 语言,用于 Oracle 数据库中的存储过程和函数的编写。PL/SQL 使用包括变量声明、条件语句、循环语句、游标操作、异常处理等。 单元测试 单元测试是软件测试的一种,旨在验证软件中的最小...

    oracle实验报告

    实验四 PL/SQL存储过程 (2学时) 【实验目的】 (1)了解存储过程的使用方法。 (2)掌握存储过程的使用方法。 【实验要求】 (1)按照业务要求创建实现特定功能的存储过程。 (2)按照业务内容创建实现具有特定功能的函数...

    Oracle中RAISE异常深入分析

    调用RAISE_APPLICATION_ERROR存储过程 当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL运行时引擎自动抛出。异常也可以通过RAISE语句抛出 RAISE exception_name; 显式抛出异常是程序员处理声明的异常的习惯...

    Oraclet中的触发器

    在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块,不过有一点不同的是,触发器是隐式调用的,并不能接收参数。 触发器优点 (1)触发器能够实施的检查和操作比主键和外键约束、...

    韩顺平oracle学习笔记

    Application,development,sql*plus,worksheet,,4)pl/sql,developer,属于第三方软件,主要用于开发,测试,优化oracle,pl/sql,的 存储过程.如:触发器,此软件oracle不带,需要单独安装。,5)oracle的企业管理器(oem,...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    10.2.5 将子查询因子化应用到PL/SQL中 270 10.3 递归子查询 273 10.3.1 一个CONNECT BY的例子 274 10.3.2 使用RSF的例子 275 10.3.3 RSF的限制条件 276 10.3.4 与CONNECT BY的不同点 276 10.4 复制CONNECT BY...

    nve:一个可以轻松存储和检索名称的实用程序

    (名称:值加密) 使用 Oracle PL/SQL 轻松存储和检索名称:值对加密 (NVE) 数据的实用程序。 该项目的目标是能够使用最强大的加密方法轻松保存敏感信息。 该项目使用 Oracle 的 dbms_crypto 包使用 256 位 AES ...

    数据库开发技术工具介绍.pptx

    * 熟悉游标、存储过程、存储函数、包以及触发器的应用 本篇资源摘要信息对数据库开发技术工具进行了详细的介绍,涵盖了Oracle数据库的发展历程、主要特点、版本等知识点,为学习数据库开发技术提供了良好的基础。

Global site tag (gtag.js) - Google Analytics