-----------------------------Cryking原创------------------------------
-----------------------转载请注明出处,谢谢!------------------------

并行处理能大大提高数据的处理速度,它依赖于硬件资源、网络资源等环境.

并行处理的硬件资源环境分为5大类:

1.传统的单台计算机、单处理器、单内核的机器.(无法进行并行处理,但是并行程序还是可以运行的,此时就和普通程序一样了)

2.单台计算机、单处理器、多内核的机器.(目前本人的测试环境,没钱买多处理器的)

3.单台计算机、多处理器、多内核的机器.

4.集群系统

5.分布式系统

PS:如何查看几个处理器、几核,常用的软件就是CPU-Z.

本人的测试机器CPU:

单CPU,双核心处理器

下面开始,编写一个普通的管道函数(这里演示的就是管道函数的并行处理):

CREATE OR REPLACE FUNCTION pipe_test
(
c_empno SYS_REFCURSOR
,p VARCHAR2 DEFAULT ','
) RETURN EMP_element
PIPELINED IS
v_element VARCHAR2(1000);
BEGIN
FETCH c_empno
INTO v_element;
LOOP
EXIT WHEN c_empno%NOTFOUND;
PIPE ROW(substr(v_element, 0, instr(v_element, p) - 1));
LOOP
v_element := substr(v_element
,instr(v_element, p) + 1
,length(v_element) - instr(v_element, p) + 1);
EXIT WHEN instr(v_element, p) = 0;
PIPE ROW(substr(v_element, 0, instr(v_element, p) - 1));
END LOOP;
PIPE ROW(v_element);
FETCH c_empno
INTO v_element;
END LOOP;
RETURN;
END pipe_test;

注意需要先建立类型EMP_element,如下:

CREATE OR REPLACE TYPE EMP_element as table of varchar2(100);

然后我们建立一个并行处理的管道函数:

CREATE OR REPLACE FUNCTION parallel_test
(
p_empno SYS_REFCURSOR
,p VARCHAR2 DEFAULT ','
) RETURN EMP_element
PIPELINED
PARALLEL_ENABLE(PARTITION p_empno BY ANY) IS
v_element VARCHAR2(1000);
BEGIN
FETCH p_empno
INTO v_element;
LOOP
EXIT WHEN p_empno%NOTFOUND;
PIPE ROW(substr(v_element, 0, instr(v_element, p) - 1));
LOOP
v_element := substr(v_element
,instr(v_element, p) + 1
,length(v_element) - instr(v_element, p) + 1);
EXIT WHEN instr(v_element, p) = 0;
PIPE ROW(substr(v_element, 0, instr(v_element, p) - 1));
END LOOP;
PIPE ROW(v_element);
FETCH p_empno
INTO v_element;
END LOOP;
RETURN;
END parallel_test;

留意下启用并行的关键字PARALLEL_ENABLE.

接下来我们构造大表进行测试,根据v$pq_sesstat视图的结果,我们来判断数据库系统是否真的进行了并行处理.

12:57:52 SYS@orcl> create table big_data as select 'Cc' a,'Dd' b from dual connect by level<1000000;

表已创建。

已用时间:  00: 00: 01.92
12:59:00 SYS@orcl> select count(*) from big_data; COUNT(*)
----------
999999 已选择 1 行。 已用时间: 00: 00: 00.31
13:47:08 SYS@orcl> set autot trace exp stat
--普通管道函数耗时40.48秒
13:48:42 SYS@orcl> select SCOTT.pipe_test(CURSOR(SELECT a||','||b from big_data)) FROM DUAL; 已选择 1 行。 已用时间: 00: 00: 40.48 执行计划
----------------------------------------------------------
Plan hash value: 2452824241 ------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 |
| 1 | VIEW | | 8168 | 414K| 29 (0)| 00:00:01 |
| 2 | COLLECTION ITERATOR PICKLER FETCH| PIPE_TEST | 8168 | | 29 (0)| 00:00:01 |
| 3 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------ Note
-----
- dynamic sampling used for this statement (level=2) 统计信息
----------------------------------------------------------
1000515 recursive calls
0 db block gets
1000325 consistent gets
1548 physical reads
0 redo size
6027769 bytes sent via SQL*Net to client
1214 bytes received via SQL*Net from client
10 SQL*Net roundtrips to/from client
7 sorts (memory)
0 sorts (disk)
1 rows processed 13:53:24 SYS@orcl> alter system flush shared_pool; 系统已更改。 已用时间: 00: 00: 01.43
--使用启用并行的管道函数,耗时40.32,与普通的管道函数耗时差不多
--奇怪的是执行计划了多了一个BIG_DATA的全表扫描操作了
13:53:26 SYS@orcl> select SCOTT.parallel_test(CURSOR(SELECT a||','||b from big_data)) FROM DUAL; 已选择 1 行。 已用时间: 00: 00: 40.32 执行计划
----------------------------------------------------------
Plan hash value: 1682567826 ---------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 | | 1 | VIEW | | 8168 | 414K| 29 (0)| 00:00:01 | | 2 | COLLECTION ITERATOR PICKLER FETCH| PARALLEL_TEST | 8168 | | 29 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL | BIG_DATA | 968K| 7565K| 422 (3)| 00:00:06 | | 4 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | ---------------------------------------------------------------------------------------------------- Note
-----
- dynamic sampling used for this statement (level=2) 统计信息
----------------------------------------------------------
1000867 recursive calls
0 db block gets
1000353 consistent gets
1560 physical reads
0 redo size
6026847 bytes sent via SQL*Net to client
1006 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
9 sorts (memory)
0 sorts (disk)
1 rows processed
--通过v$pq_sesstat视图我们发现此时系统并没有进行并行处理,(其实通过执行计划也可看出没有使用并行)
13:54:21 SYS@orcl> select * from v$pq_sesstat; STATISTIC LAST_QUERY SESSION_TOTAL
------------------------------ ---------- -------------
Queries Parallelized 0 0
DML Parallelized 0 0
DDL Parallelized 0 0
DFO Trees 0 0
Server Threads 0 0
Allocation Height 0 0
Allocation Width 0 0
Local Msgs Sent 0 0
Distr Msgs Sent 0 0
Local Msgs Recv'd 0 0
Distr Msgs Recv'd 0 0 已选择11行。 已用时间: 00: 00: 00.00 13:54:40 SYS@orcl> alter system flush buffer_cache; 系统已更改。 已用时间: 00: 00: 00.00
13:55:27 SYS@orcl> alter system flush shared_pool; 系统已更改。 已用时间: 00: 00: 01.40
--接下来我们加HINT,强制并行处理,此时耗时25.03秒,降低了一半
13:55:30 SYS@orcl> select /*+ parallel */scott.PARALLEL_TEST(CURSOR(SELECT a||','||b from big_data))
FROM DUAL; 已选择 1 行。 已用时间: 00: 00: 25.03 执行计划
----------------------------------------------------------
Plan hash value: 3127237831 ----------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib | ----------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 | | | | | 1 | PX COORDINATOR | | | | | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10000 | 8168 | 414K| 16 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) | | 3 | VIEW | | 8168 | 414K| 16 (0)| 00:00:01 | Q1,00 | PCWP | | | 4 | COLLECTION ITERATOR PICKLER FETCH| PARALLEL_TEST | 8168 | | 16 (0)| 00:00:01 | Q1,00 | PCWP | | | 5 | PX BLOCK ITERATOR | | 968K| 7565K| 234 (3)| 00:00:03 | Q1,00 | PCWC | | | 6 | TABLE ACCESS FULL | BIG_DATA | 968K| 7565K| 234 (3)| 00:00:03 | Q1,00 | PCWP | | | 7 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | | ----------------------------------------------------------------------------------------------------------------------------------- Note
-----
- dynamic sampling used for this statement (level=2)
- automatic DOP: Computed Degree of Parallelism is 2 统计信息
----------------------------------------------------------
1000941 recursive calls
4 db block gets
1000516 consistent gets
1842 physical reads
0 redo size
6026847 bytes sent via SQL*Net to client
1006 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
9 sorts (memory)
0 sorts (disk)
1 rows processed
--上面的执行计划及v$pq_sesstat都显示系统启用了并行处理,并行度为2
13:57:44 SYS@orcl> select * from v$pq_sesstat; STATISTIC LAST_QUERY SESSION_TOTAL
------------------------------ ---------- -------------
Queries Parallelized 0 1
DML Parallelized 0 0
DDL Parallelized 0 0
DFO Trees 0 1
Server Threads 0 0
Allocation Height 0 0
Allocation Width 0 0
Local Msgs Sent 0 553
Distr Msgs Sent 0 0
Local Msgs Recv'd 0 553
Distr Msgs Recv'd 0 0 已选择11行。 已用时间: 00: 00: 00.01

为了使示例更加有说服力,我们再来试一下普通管道函数+HINT强制并行看看:

16:02:36 SYS@orcl> select /*+ parallel */SCOTT.pipe_test(CURSOR(SELECT a||','||b from big_data)) FROM DUAL;

已选择 1 行。

已用时间:  00: 00: 43.34

执行计划
----------------------------------------------------------
Plan hash value: 2452824241 ------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 |
| 1 | VIEW | | 8168 | 414K| 16 (0)| 00:00:01 |
| 2 | COLLECTION ITERATOR PICKLER FETCH| PIPE_TEST | 8168 | | 16 (0)| 00:00:01 |
| 3 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------ Note
-----
- dynamic sampling used for this statement (level=2)
- automatic DOP: Computed Degree of Parallelism is 1 统计信息
----------------------------------------------------------
1003093 recursive calls
18 db block gets
1000973 consistent gets
1628 physical reads
0 redo size
6026843 bytes sent via SQL*Net to client
1006 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
100 sorts (memory)
0 sorts (disk)
1 rows processed

由于普通函数不支持并行,所以即使+HINT强制并行,系统还是没有使用并行处理.耗时依然为40多秒.

如果不使用函数,使用普通的SQL,又是可以使用HINT强制并行的,如下:

15:59:07 SYS@orcl> select /*+ parallel */ a||','||b from big_data;

已选择999999行。

已用时间:  00: 00: 04.09

执行计划
----------------------------------------------------------
Plan hash value: 2638980575 --------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 968K| 7565K| 234 (3)| 00:00:03 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 968K| 7565K| 234 (3)| 00:00:03 | Q1,00 | P->S | QC (RAND) |
| 3 | PX BLOCK ITERATOR | | 968K| 7565K| 234 (3)| 00:00:03 | Q1,00 | PCWC | |
| 4 | TABLE ACCESS FULL| BIG_DATA | 968K| 7565K| 234 (3)| 00:00:03 | Q1,00 | PCWP | |
-------------------------------------------------------------------------------------------------------------- Note
-----
- dynamic sampling used for this statement (level=2)
- automatic DOP: Computed Degree of Parallelism is 2 统计信息
----------------------------------------------------------
6 recursive calls
0 db block gets
1577 consistent gets
1520 physical reads
0 redo size
13467035 bytes sent via SQL*Net to client
733742 bytes received via SQL*Net from client
66668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
999999 rows processed

通过上面的示例可以看到,并行处理可以大大加速数据的处理,几乎成倍的提升性能.

但并不是并行度为几,就会提示几倍的性能,它受硬件环境,优化器内部算法,PL/SQL引擎解析等等的约束.

总之,并行处理给我们带来的性能提升是很大的,所以在某些场景使用并行编程也是很必要的.

初试PL/SQL并行编程的更多相关文章

  1. PL/SQL存储过程编程

    PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...

  2. oracle PL/SQL基础编程

    PL/SQL(Procedural Language/SQL)是oracle中引入的一种过程化编程语言 PLS-00103:出现符号"declare"在需要下列之一时 符号&quo ...

  3. PL/SQL 基础编程

    PL/Sql 编程 PL/Sql结构 [declare] --声明变量 begin --执行部分 [exception] ---异常处理部分 end PL/Sql  基本数据类型 数值类型 1. nu ...

  4. Oracle数据库—— PL/SQL进阶编程

    一.涉及内容 1.掌握PL/SQL程序块的结构 2.理解并熟练掌握各种变量的应用. 二.具体操作 1.创建一个表messages,该表只有一个字段results 类型是number(2),编写一个块, ...

  5. Oracle数据库—— PL/SQL基础编程

    一.涉及内容 1. 掌握PL/SQL程序块的结构,理解并熟悉各种变量的应用. 二.具体操作 (一)使用system用户登录SQL*PLUS,使用SQL语句创建用户:u_你的姓名首字母(例如:u_zs) ...

  6. Oracle PL/SQL 高级编程

    1. 复合数据类型--记录类型 Ø        语法格式 type  类型名 is   record ( 字段1  字段1类型 [not null]:=表达式1; 字段2  字段2类型 [not n ...

  7. 【学亮IT手记】PL/SQL游标编程

    游标提供了一种从表中检索数据并进行操作的灵活手段,主要用在服务器上,处理由客户端发送给服务器端的sql语句,或者是批处理.存储过程.触发器中的数据处理请求. 显式游标 是由用户声明和操作的一种游标,通 ...

  8. Oracle PL/SQL DBA 编程实践基础

    [附:一文一图]

  9. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

随机推荐

  1. BZOJ 1037: [ZJOI2008]生日聚会Party( dp )

    dp(i, j, a, b)表示选了i个男生, j个女生, 后缀中男生比女生多a(最多), 女生比男生多b(最多). dp(i+1, j, a+1, max(0, b-1)) += dp(i, j, ...

  2. 求模和求余(附加C语言实现)

    求模和求余的总体计算步骤如下: 1.求整数商  c = a/b 2.计算模或者余数 r = a - c*b 求模和求余的第一步不同,求余在取c的值时向0方向舍入;取模在计算c的值时向无穷小方向舍入. ...

  3. java 线程学习

    转载:详见处http://lavasoft.blog.51cto.com/62575/27069   Java多线程编程总结   下面是Java线程系列博文的一个编目:   Java线程:概念与原理 ...

  4. 在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be closed first”

    在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be ...

  5. ODI中的CDC

    ODI中的CDC是通过一组所谓的日志知识模块(Journal Knowledge Module,JKM)实现的,在项目中加在了这些模块后,就可以在接口设计时选择全量数据,还是变化数据.   ODI共提 ...

  6. 射频识别技术漫谈(28)——基于MF1射频卡的酒店门锁设计

    电子门锁是现代星级酒店管理电子化.智能化的重要电子设备.相较于传统的机械锁,基于RFID技术的电子门锁使用方便,易于管理,安全性高,可实现对开锁用户的分优先级自动管理,对房间入住信息实现自动统计与报表 ...

  7. 深入剖析PE文件

    不赖猴的笔记,转载请注明出处. 深入剖析PE文件 PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解. 一.   ...

  8. Openstack命令收集

    查看rabbitmq 队列 rabbitmqctl list_queues 查看keystone的用户 keystone user-list 查看keystone endpoint keystone ...

  9. js正则验证"汉字"

    var nickname = value; var regex = new RegExp("^([\u4E00-\uFA29]|[\uE7C7-\uE7F3]|[a-zA-Z0-9_]){1 ...

  10. Database(Mysql)发版控制二

    author:skate time:2014/08/18 Database(Mysql)发版控制 The Liquibase Tool related Database 一.Installation ...