精华内容
下载资源
问答
  • 并行调用存储过程时间长
    2020-12-18 21:11:41

    背景:

    最近遇到一个case,Client端程式调用存储过程SP1,过程SP1执行完成后返回结果到Client。

    因为过程SP1执行时间要5秒钟,时间太长Client用户无法接受。

    分析主过程SP1性能,发现主要是其中调用的子过程SP2执行需要4秒,且子过程SP2中一条SQL因为资料量巨大逻辑复杂已无优化可能。另外子过程SP2的主要是计算审计功能并记录日志作用的。

    设想:

    能否让用户执行主过程时不等子过程完成就

    直接返回结果

    ,子过程异步方式在后台慢慢的运行?

    直接通过Oracle的技术能否实现?

    答案是可以的,通过DBMS_JOB.SUBMIT 下面的方法可以实现。

    实现:

    创建log表:

    CREATE TABLE SFIS1.JOBSUBMIT_LOG

    (

    EXE_TIME  DATE,

    DATAX     VARCHAR2(5 BYTE)

    )

    创建子过程:

    CREATE OR REPLACE PROCEDURE SFIS1.JOB_SUBMIT (DATA3  IN  VARCHAR2)

    IS

    BEGIN

    IF DATA3='1' THEN

    dbms_lock.sleep(10); --模拟子过程执行10秒需要

    insert into sfis1.jobsubmit_log values(SYSDATE,DATA3);

    ELSE

    insert into sfis1.jobsubmit_log values(SYSDATE,DATA3);

    END IF;

    commit;

    EXCEPTION

    WHEN OTHERS

    THEN

    DBMS_OUTPUT.PUT_LINE('FAIL2!');

    END;

    创建主过程:

    CREATE OR REPLACE PROCEDURE SFIS1.JOB_SP (DATA1  IN  VARCHAR2,DATA2  IN  VARCHAR2)

    IS

    START_TIME   DATE;

    l_job        NUMBER;

    BEGIN

    START_TIME := SYSDATE;

    DBMS_OUTPUT.PUT_LINE ('Start Time:' || TO_CHAR (START_TIME, 'YYYY-MM-DD-HH24:MI:SS'));

    DBMS_JOB.submit (l_job, 'SFIS1.JOB_SUBMIT('||data1||');');

    DBMS_JOB.submit (l_job, 'SFIS1.JOB_SUBMIT('||data2||');');

    COMMIT;

    DBMS_OUTPUT.PUT_LINE ('Elapsed Time:' || CEIL ( (SYSDATE - START_TIME) * 24 * 60 * 60)); --计算主过程运行总时间

    EXCEPTION

    WHEN OTHERS

    THEN

    DBMS_OUTPUT.PUT_LINE ('FAIL!');

    END;

    执行主过程:

    exec SFIS1.JOB_SP('1','2');

    结果:

    Start Time:2019-06-04-10:11:12

    Elapsed Time:0 --执行时间0秒,说明子过程已经异步在后台执行了,主过程并没有等待子过程执行完成

    查询log表:

    select * from sfis1.jobsubmit_log;

    2019/6/4 10:11:13     2

    2019/6/4 10:11:23     1   --进一步说明子过程异步在后台执行

    以上,主要通过

    DBMS_JOB.SUBMIT

    并行异步后台执行存储过程。

    本文使用技术主要参考Tom大师:

    更多相关内容
  • Oracle并行调用存储过程

    千次阅读 2019-01-09 23:33:00
    Oracle并行调用存储过程 网上很少看到有对Oracle并行的介绍,下面通过Oracle中的dbms_job包实现存储过程并行调用: create table a(id number); create table b(id number); create or replace procedure pro_a ...

    Oracle并行调用存储过程

    网上很少看到有对Oracle并行的介绍,下面通过Oracle中的dbms_job包实现存储过程的并行调用:

    create table a(id number);
    create table b(id number);
    
    create or replace procedure pro_a is
    begin
      for i in  1 .. 10 loop
        insert into a values (i);
        dbms_lock.sleep(5);
        commit;
      end loop;
    end;
    /
    
    create or replace procedure pro_b(v_num in number default 10) is
    begin
      for i in reverse 1 .. v_num loop
        insert into b values (10+i);
        dbms_lock.sleep(5);
        commit;
      end loop;
    end;
    /
    
    -- 串行
    begin
      pro_a;
      pro_b;
    end;
    /
    
    CREATE OR REPLACE PROCEDURE pro_job(pro_name in varchar2) as
      v_job binary_integer;
    begin
      -- 通过一个job一个存储过程来实现并行调用
      dbms_job.submit(v_job,pro_name);
      dbms_output.put_line(v_job);
      commit;
    end;
    /
    
    -- 并行执行存储过程
    begin
      pro_job('pro_a;');
      pro_job('pro_b(''7'');');
    end;
    /
    
    --查询是否并行
    select * from a;
    select * from b;
    
    --删除重新实验
    --delete from a;
    --delete from b;
    --commit;
    
    --查询job的运行情况
    select * from user_jobs;
    select * from dba_jobs_running;
    

    也可以使用DBMS_SCHEDULER来实现,可参考
    https://docs.oracle.com/cd/E11882_01/server.112/e25494/appendix_a.htm#ADMIN11002

    展开全文
  • Oracle11gR2 并行执行存储过程

    千次阅读 2019-06-19 18:14:59
    现在我们有3个存储过程,分别是p1,p2,p3 如果按下列方式执行 begin p1; p2; p3; end; 它们是串行的。 我们可以使用DBMS_SCHEDULER包来间接实现并行执行,具体用法如下: begin dbms_scheduler.create_job...

    现在我们有3个存储过程,分别是p1,p2,p3

    如果按下列方式执行

    begin
        p1;
        p2;
        p3;
    end;

    它们是串行的。

    我们可以使用DBMS_SCHEDULER包来间接实现并行执行,具体用法如下:

    begin
      dbms_scheduler.create_job(job_name   => dbms_scheduler.generate_job_name,
                                job_type   => 'PLSQL_BLOCK',
                                job_action => 'begin p1; end;',
                                start_date => sysdate,
                                enabled    => true,
                                comments   => 'temporary job,will be delete soon after complete!',
                                auto_drop  => true
                                );
      dbms_scheduler.create_job(job_name   => dbms_scheduler.generate_job_name,
                                job_type   => 'PLSQL_BLOCK',
                                job_action => 'begin p2; end;',
                                start_date => sysdate,
                                enabled    => true,
                                comments   => 'temporary job,will be delete soon after complete!',
                                auto_drop  => true
                                );                            
      dbms_scheduler.create_job(job_name   => dbms_scheduler.generate_job_name,
                                job_type   => 'PLSQL_BLOCK',
                                job_action => 'begin p3; end;',
                                start_date => sysdate,
                                enabled    => true,
                                comments   => 'temporary job,will be delete soon after complete!',
                                auto_drop  => true
                                );
    end;

    使用create_job来创建并立即执行一个job,执行完之后系统会自动删除。其中:

    dbms_scheduler.generate_job_name 用来创建一个job_name,默认是JOB$_加上一个递增的数字,形如 JOB$_7983

    start_time => sysdate 表示立即执行(需要同时将enabled设置为true)

    enabled => true 只有这样才会立即执行

    auto_drop => true 表示执行完自动删除

    由于我们没有指定任何重复执行的参数,所以job创建后,它的SCHEDULE_TYPE=ONCE,而不是一般的CALENDAR。

    可以通过

    select * from user_scheduler_jobs;

    查看。

    在我的工作中遇到这么一个实际需求,伪代码如下:
     

    begin
    for rows in (select COL1 from tab) loop
        业务逻辑处理;
    end loop;
    end;

    处理逻辑部分比较简单,但是循环次数比较多,所以考虑将数据分片执行。

    begin
      for rows in (select col1
                     from (select mod(rownum, v_parallel_degree) + 1 part,
                                  --part要加1,因为是取余
                                  col1
                             from (select col1 from tab order by col2))
                    where part = v_part) loop
      end loop;
    end;
    
    其中:
     v_parallel_degree:分片的数量
     v_part:用来取第x分片

    将以上代码放到存储过程中,两个入参:v_parallel_degree,v_part

    最后使用一个存储过程来调用

    --***************************创建一个工具包用来创建job***************************
    
    create or replace package pkg_utils is
    
      procedure exec_pkg(v_pkg_name in varchar2);
    
      --并行执行存储过程
      procedure exec_proc_parallel(v_procedure_name  in varchar2,
                                   v_parallel_degree in int);
    
    end pkg_utils;
    
    /
    create or replace package body pkg_utils is
    
      --并行执行存储过程
      procedure exec_proc_parallel(v_procedure_name  in varchar2,
                                   v_parallel_degree in int) is
      
      begin
        for i in 1 .. v_parallel_degree loop
          dbms_scheduler.create_job(job_name   => dbms_scheduler.generate_job_name,
                                    job_type   => 'PLSQL_BLOCK',
                                    job_action => 'begin ' || v_procedure_name || '(' ||
                                                  v_parallel_degree || ',' || i ||
                                                  '); end;',
                                    start_date => sysdate,
                                    enabled    => true,
                                    comments   => v_procedure_name || '(' || i ||
                                                  ' of ' || v_parallel_degree || ')',
                                    auto_drop  => true);
        end loop;
      end exec_proc_parallel;
    
    begin
      -- initialization
      null;
    end pkg_utils;
    /
    
    --***************************调用实例***************************
    begin
      pkg_utils.exec_proc_parallel('PROCEDURE_NAME', 16);
    end;
    /

     

    展开全文
  • oracle并行执行存储过程的小案例前言一、操作流程1.查询一下create job的权限2.建日志表和可延时的存储过程来测试并行和串行执行存储过程的效果3.执行并行和串行的plsql来测试 前言 Oracle的dbms_scheduler包也可以...


    前言

    Oracle的dbms_scheduler包也可以创建Job,来定时、并行执行任务。下面给一个测试的小案例,方便入门。


    一、操作流程

    1.查询一下create job的权限

    代码如下:

    Select * From Session_Privs;
    

    在这里插入图片描述
    如果没有Create Job权限,可以参考:https://blog.csdn.net/crystal201314/article/details/100454496

    2.建日志表和可延时的存储过程来测试并行和串行执行存储过程的效果

    代码如下:

    --创建日志表,记录进表的时间,logid可以插入序列号
    create table LOG1
    (
      logid VARCHAR2(20),
      daten DATE
    );
    -- Create sequence 
    create sequence seq_logid
    minvalue 1
    maxvalue 999999999
    start with 1
    increment by 1
    cache 20;
    
    --创建延时的存储过程
    create or replace procedure test_sleep is
    datenow date;
    begin
      insert into log1(LOGID,daten) select seq_logid.nextval,sysdate from dual;
      commit;
    select sysdate + + 1/24/60*1 into datenow from dual;
    loop
    
    exit when datenow < sysdate;
    end loop;
       insert into log1(LOGID,daten) select seq_logid.nextval,sysdate from dual;
    commit;
    end;
    

    3.执行并行和串行的plsql来测试

    代码如下:

    --并行plsql
    begin
      dbms_scheduler.create_job(job_name => 'xxx1',
                                job_type => 'PLSQL_BLOCK',
                                job_action => 'begin test_sleep; end;',
                                start_date => sysdate,
                                enabled => true,    
                                comments => 'temporary job,will be delete soon after complete!',        
                                auto_drop => true
                                );
        dbms_scheduler.create_job(job_name => 'xxx2',
                                job_type => 'PLSQL_BLOCK',
                                job_action => 'begin test_sleep; end;',
                                start_date => sysdate,
                                enabled => true,    
                                comments => 'temporary job,will be delete soon after complete!',        
                                auto_drop => true
                                );
       dbms_scheduler.create_job(job_name => 'xxx3',
                                job_type => 'PLSQL_BLOCK',
                                job_action => 'begin test_sleep; end;',
                                start_date => sysdate,
                                enabled => true,    
                                comments => 'temporary job,will be delete soon after complete!',        
                                auto_drop => true
                                );
    end;
    
    --串行plsql
    begin
    test_sleep;
    test_sleep;
    test_sleep;
    end;
    

    分别执行并行和串行plsql,并行plsql会同时执行存储过程test_sleep,而串行plsql后面的存储过程需要等前面的执行完才会执行。执行完成之后,查看日志表,看并行、串行执行存储过程的效果。

    在这里插入图片描述


    展开全文
  • 存储过程内容是有对多个表查询、插入、更新等操作。 假如一个存储过程执行要10s。启动了10个java线程同时调用同一个存储过程存储过程并行还是串行,要10s还是100s?  </p>
  • oracle存储过程通过JOB来实现并行执行
  • -- 建立测试表 CREATE TABLE t (a NUMBER)...-- 建立存储过程 CREATE OR REPLACE PROCEDURE p_parallel (p_min IN NUMBER, p_max IN NUMBER) IS BEGIN INSERT INTO t SELECT TRUNC (DBMS_RANDOM.VALUE (p_min, p_m...
  • 问题在于最后一行,它无法调用任何一个存储过程。SQL * Plus中的三种选择是:call,exec和一个有害的PL/SQL块。CALL test_sp_1();一位不愿具名的PL/SQL块是PL/SQL不是一个命名过程,函数,触发器中,等它可以用来打...
  • Mysql存储过程执行顺序问题SQL code:CREATE TABLE `t_a` (`a_id` int(11) NOT NULL AUTO_INCREMENT,`a_name` varchar(30) NOT NULL DEFAULT 'N/A',PRIMARY KEY (`a_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;...
  • 关于存储过程并发处理解决方案

    千次阅读 2021-05-02 01:28:07
    2013-01-05浏览:116次关于存储过程并发处理想测试一下存储过程处理过程中,另一个进程也调用了当前存储过程时,数据一致性的问题,现做了以下测试:创建表A100(可理解成库存总量表)C1varchar2(10)--产品编码C...
  • oracle存储过程执行sql

    千次阅读 2019-09-05 16:41:46
    --这里演示的是备份表 可以多个表,如果需要请留言 DECLARE sql_tem VARCHAR2(110); tableName VARCHAR2(110); BEGIN SELECT 'APP_TABLE_'||TO_CHAR(SYSDATE,'yyyymmddhh24miss') into tableName FROM dual;...
  • Oracle并行执行

    2012-02-09 23:55:05
    Oracle并行执行
  • 并行执行时,数据需要分发,本质上是因为Oracle采用share---everything的集中存储架构,任何数据对每个实例的PX进程都是共享的。为了对hashjoin操作分而治之,切分为N个独立的工作单元(假设DoP=N),必须提前对数据...
  • 该优化器基于一些条件来评估成本,包括CPU并行性和速度、I/O存储特征和通信带宽等外部条件,以及DB2注册表变量、DB2优化级别、统计信息等内部条件。而且,在系统运行时期间,这些条件中许多都在不断变化,所以选择...
  • mysql执行存储过程

    2016-12-27 15:09:40
    call sp_add(); 是不是你定义的过程有问题吧,并没有指出返回结果来 像我这样是可以的: CREATE PROCEDURE sp_add(a int, b int,out c int) begin ...调用过程: call sp_add (1,2,@a); select @a;
  • 由于最近的工作基本都是在与shell和存储过程打交道,任何任务的开始都是以shell脚本开始,之前的任务是通过shell并行执行,后续的任务依赖于并行的任务是否执行完毕,下一个shell如果获取并行任务是否结束成为了一个...
  • 项目6总结:创建与使用存储过程

    千次阅读 2022-05-12 16:33:15
    主要是创建简单存储过程,游标的存储过程及创建和使用事务
  • 利用job并行执行Oracle存储过程

    千次阅读 2016-12-28 11:13:26
    -- 建立测试表 CREATE ... -- 建立存储过程 CREATE OR REPLACE PROCEDURE p_parallel (p_min IN NUMBER, p_max IN NUMBER) IS BEGIN INSERT INTO t SELECT TRUNC (DBMS_RANDOM.VALUE (p_min,
  • 【MySQL/MariaDB】存储过程学习记录

    千次阅读 2017-06-02 12:28:24
    存储过程 (Stored Procedure),是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象,它可以视为数据库中的一种函数或子程序。
  • 工人线程测试该存储库测试Node.JS工作线程的并行执行。 在安装了Node.JS 10.5.0的情况下,使用命令“ npm start”运行此命令。
  • Oracle--存储过程概述、创建和执行

    千次阅读 2020-01-04 18:27:25
    存储过程是一种命名PL/SQL程序块,它将一些相关的SQL语句、流程控制语句组合在一起,用于执行某些特定的操作或者任务,可以将经常需要执行的特定的操作写成过程。通过过程名,就可以多次调用过程,从而实现程序的...
  • Sqlserver定时执行存储过程

    千次阅读 2016-11-10 17:28:02
    --方法1:作业里定时执行存储过程定时作业的制定    企业管理器  --管理  --SQL Server代理  --右键作业  --新建作业  --"常规"项中输入作业名称  --"步骤"项  --新建  --...
  • 针对现有算法存储结构简单、生成大量冗余的候选集、时间和空间复杂度高、挖掘效率不理想的情况,为了进一步提高关联规则算法挖掘频繁集的速度,优化算法的执行性能,提出基于内存结构改进的关联规则挖掘算法。...
  • 通过观察执行计划,发现之前的执行计划在...由于语句是在存储过程中实现,因此我们直接对该语句使用一个undocument查询提示,使得该查询的并行开销阈值强制降为0,使得该语句强制走并行,语句执行时间由20秒降为5秒(注
  • 由于RISC具有指令长度一致、单周期执行时间、易于并行和流水线处理等优点,绝大多数的DSP处理芯片都采用了RISC.另外,根据计算机的存储器结构及其总线连接形式,计算机系统可以被分为冯诺依曼结构和哈佛结构,前者...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 304,959
精华内容 121,983
热门标签
关键字:

并行调用存储过程时间长