5

问答榜上引发的oracle并行的探究(一) -m6米乐安卓版下载

原创 2022-10-16
894

一、背景

  在冲刺“问答榜”的时候发现在了一个关于并行的问题,自己对oracle的并行也是一知半解的状态,于是自己趁这个机会也充充电。

小小吐槽一下:)
  最近的“问答榜”竞争的太激烈了,我这都翻到了2022-01-05的问题了!不得不增加自己的知识储备了,

二、简介:并行

  并行执行的原理概括起来就是“分而治之(divide and conquer)”,把一个大任务拆分成多个小的子任务,并把该任务的执行方式由一个单进程/线程依次顺序执行改成由多个进程/线程同时并发执行,而且每个子进程/线程只执行拆分后的任务。
  并行执行的本质就是以额外的硬件资源消耗来换取执行时间的缩短。硬件资源利用得越好,越高效,并行执行的时间就会越短。

注意:并行执行并不一定会缩短执行时间,它并不适合所有的场景。

三、并行真正发挥作用的条件:

1.非常有效率的执行计划,如果执行计划本身非常差,使用并行可能并不能改善多少语句的执行效率。
2.数据库系统有着充足的资源可用。
3.工作量的分配没有明显的倾斜,根据短板理论,如果某一个px slave干了很多活,那么最大的瓶颈就是它。

四、oracle里能够并行执行的操作:

测试表:
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects;

1、并行查询

  • 单表并行
-- 开启2个并行:
14:13:37 sql> select /*  parallel(2) */ count(*) from t1;
  count(*)
----------
     76833
elapsed: 00:00:00.19
execution plan
----------------------------------------------------------
plan hash value: 3110199320
--------------------------------------------------------------------------------------------------------
| id  | operation              | name     | rows  | cost (%cpu)| time     |    tq  |in-out| pq distrib |
--------------------------------------------------------------------------------------------------------
|   0 | select statement       |          |     1 |   166   (0)| 00:00:01 |        |      |            |
|   1 |  sort aggregate        |          |     1 |            |          |        |      |            |
|   2 |   px coordinator       |          |       |            |          |        |      |            |
|   3 |    px send qc (random) | :tq10000 |     1 |            |          |  q1,00 | p->s | qc (rand)  |
|   4 |     sort aggregate     |          |     1 |            |          |  q1,00 | pcwp |            |
|   5 |      px block iterator |          | 75850 |   166   (0)| 00:00:01 |  q1,00 | pcwc |            |
|   6 |       table access full| t1       | 75850 |   166   (0)| 00:00:01 |  q1,00 | pcwp |            |
--------------------------------------------------------------------------------------------------------
  • 多表关联
14:23:38 sql> select  /*  parallel(2) */t1.owner,t1.object_name,t2.status 
from t1,t2 
where t1.object_id=t2.object_id and t1.owner='scott';
11 rows selected.
elapsed: 00:00:00.27
execution plan
----------------------------------------------------------
plan hash value: 3350059367
-----------------------------------------------------------------------------------------------------------------
| id  | operation               | name     | rows  | bytes | cost (%cpu)| time     |    tq  |in-out| pq distrib |
-----------------------------------------------------------------------------------------------------------------
|   0 | select statement        |          |    12 |  1368 |   334   (1)| 00:00:01 |        |      |            |
|   1 |  px coordinator         |          |       |       |            |          |        |      |            |
|   2 |   px send qc (random)   | :tq10001 |    12 |  1368 |   334   (1)| 00:00:01 |  q1,01 | p->s | qc (rand)  |
|*  3 |    hash join            |          |    12 |  1368 |   334   (1)| 00:00:01 |  q1,01 | pcwp |            |
|   4 |     px receive          |          |    12 |  1152 |   167   (1)| 00:00:01 |  q1,01 | pcwp |            |
|   5 |      px send broadcast  | :tq10000 |    12 |  1152 |   167   (1)| 00:00:01 |  q1,00 | p->p | broadcast  |
|   6 |       px block iterator |          |    12 |  1152 |   167   (1)| 00:00:01 |  q1,00 | pcwc |            |
|*  7 |        table access full| t1       |    12 |  1152 |   167   (1)| 00:00:01 |  q1,00 | pcwp |            |
|   8 |     px block iterator   |          | 93976 |  1651k|   167   (1)| 00:00:01 |  q1,01 | pcwc |            |
|*  9 |      table access full  | t2       | 93976 |  1651k|   167   (1)| 00:00:01 |  q1,01 | pcwp |            |
-----------------------------------------------------------------------------------------------------------------

2、并行ddl

oracle数据库的ddl语句如果并行执行,通常情况下都可以缩短执行时间。

  • 准备数据相同的2张表:t1、t3
14:29:35 sql> select count(*) from t1;
  count(*)
----------
   4917312
14:29:41 sql> create table t3 as select * from t1;
table created.
14:31:01 sql> select count(*) from t3;
  count(*)
----------
   4917312
  • 在表t1上串行创建索引idx_t1:耗时:25.93s
sql> create index idx_t1 on t1(object_name,object_id,data_object_id);
index created.
elapsed: 00:00:25.93
  • 在表t3上8个并行创建索引idx_t3:耗时:18.34s
sql>  create index idx_t3 on t3(object_name,object_id,data_object_id) parallel 8;
index created.
elapsed: 00:00:11.64
  • 并行比串行提升:55%
sql> select (25.93-11.64)/25.93*100 from dual;
(25.93-11.64)/25.93*100
-----------------------
             55.1099113
  • 注:oracle 在并行执行完ddl语句后,可能会导致相关对像默认并行度的变化:
    oracle 在访问索引idx_t3的时候,cbo可能会考虑并行执行,这可能会引发一系列的问题。
    所以在并行执行完ddl语句后通常应该将相关对象的并行度调整为:1
sql> select index_name,degree from dba_indexes where index_name like 'idx_t%';
index_name                     degree
------------------------------ ----------------------------------------
idx_t3                         8   <--- 8个并行创建的索引,并行度为:8
idx_t1                         1   <--- 串行创建索引,并行度为:1
  • 将索引idx_t3并行度调整为:1
sql> alter index idx_t3 noparallel;
index altered.
elapsed: 00:00:00.01
sql>  select index_name,degree from dba_indexes where index_name like 'idx_t3';
index_name                     degree
------------------------------ ----------------------------------------
idx_t3                         1

3、并行dml

oracle数据库的dml语句如果并行执行,通常情况下都可以缩短执行时间。

  • 示例:
-- 串行:
sql> update t1 set object_name='cuihua1';
4917312 rows updated.
elapsed: 00:02:40.80
execution plan
----------------------------------------------------------
plan hash value: 2927627013
---------------------------------------------------------------------------
| id  | operation          | name | rows  | bytes | cost (%cpu)| time     |
---------------------------------------------------------------------------
|   0 | update statement   |      |  4785k|   301m| 18999   (1)| 00:03:48 |
|   1 |  update            | t1   |       |       |            |          |
|   2 |   table access full| t1   |  4785k|   301m| 18999   (1)| 00:03:48 |
---------------------------------------------------------------------------
-- 并行:启用并行hint
sql> update /*  parallel(4) */ t1 set object_name='cuihua1';
4917312 rows updated.
elapsed: 00:02:49.69
execution plan
----------------------------------------------------------
plan hash value: 121765358
---------------------------------------------------------------------------------------------------------------
| id  | operation             | name     | rows  | bytes | cost (%cpu)| time     |    tq  |in-out| pq distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | update statement      |          |  4785k|   301m|  5271   (1)| 00:00:11 |        |      |            |
|   1 |  update               | t1       |       |       |            |          |        |      |            |
|   2 |   px coordinator      |          |       |       |            |          |        |      |            |
|   3 |    px send qc (random)| :tq10000 |  4785k|   301m|  5271   (1)| 00:00:11 |  q1,00 | p->s | qc (rand)  |
|   4 |     px block iterator |          |  4785k|   301m|  5271   (1)| 00:00:11 |  q1,00 | pcwc |            |
|   5 |      table access full| t1       |  4785k|   301m|  5271   (1)| 00:00:11 |  q1,00 | pcwp |            |
-------------------------------------------------------------------------------------------------------------

启用并行hint执行上述更新操作后发现执行时间反而增加了9s左右。从执行计划上面来看,更新操作的并行部分全部发生在全表扫描t1的部分,而真正的update 则是发生在p->s(表示parallel_to_serial)之后,即这里启用并行hint的更新操作是一个伪并行更新操作。在这个伪并行更新操作里,真正的更新操作并没有并行执行,实际的并行操作全部发生在并行扫描表t1上,更新操作成为了上述sql在并行执行扫描表t1后的瓶颈,因此执行速度反而更慢了。

  • 现在我们执行真正的并行更新:
......前面事务未结束
sql> alter session force parallel dml;
error:
ora-12841: cannot alter the session parallel dml state within a transaction
elapsed: 00:00:00.03
-- 结束事务,重启事务
sql> commit;
commit complete.
elapsed: 00:00:00.04
sql> alter session force parallel dml;
session altered.
elapsed: 00:00:00.00
sql> update t1 set object_name='cuihua1';
4917312 rows updated.
elapsed: 00:01:22.97
sql> commit;

串行的:00:02:40.80,原并行:00:02:49.69,真实并行: 00:01:22.97,整整提高了1分20秒左右
– 注:alter session force parallel dml;执行完一个dml语句后需要结束事务(commit/rollback),
否则会报:ora-12841: cannot alter the session parallel dml state within a transaction
所以set autotrace on 无法与alter session force parallel dml 一起使用。

sql> set autotrace on
sql>  update t1 set object_name='cuihua1';
4917312 rows updated.
elapsed: 00:01:22.43
execution plan
---------------------------------------------------------
error:
ora-12838: cannot read/modify an object after modifying it in parallel
sp2-0612: error generating autotrace explain report

– 查看执行计划:

--  用于刚刚执行过的sql,真实的执行计划
sql> select * from table(dbms_xplan.display_cursor(null,null,'advanced'));
plan_table_output
--------------------------
sql_id  12nxhwc2ugdm6, child number 1
-------------------------------------
update t1 set object_name='cuihua1'
plan hash value: 3991856572
---------------------------------------------------------------------------------------------------------------
| id  | operation             | name     | rows  | bytes | cost (%cpu)| time     |    tq  |in-out| pq distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | update statement      |          |       |       |   439 (100)|          |        |      |            |
|   1 |  px coordinator       |          |       |       |            |          |        |      |            |
|   2 |   px send qc (random) | :tq10000 |  4785k|   301m|   439   (1)| 00:00:06 |  q1,00 | p->s | qc (rand)  |
|   3 |    update             | t1       |       |       |            |          |  q1,00 | pcwp |            |
|   4 |     px block iterator |          |  4785k|   301m|   439   (1)| 00:00:06 |  q1,00 | pcwc |            |
|*  5 |      table access full| t1       |  4785k|   301m|   439   (1)| 00:00:06 |  q1,00 | pcwp |            |
---------------------------------------------------------------------------------------------------------------

– 从执行计划可以看到,更新操作是真正的并行执行的,并行部分不仅发生在全表扫描表t1的部分,而且也发生在更新部分。所对应的是pcwp(表示parallel_combined_with_parent),这就表明上述更新操作确实是在并发执行。
知识小点:
除了“alter session force parallel dml;”可以真正并行执行dml操作之外,“alter session enable parallel dml;” 并行hint的dml语句联合使用也同样可以达到 真正并行执行dml操作的目的。
注意:仅仅修改表的并行度仅使用并行hint ,都不能真正并行执行dml.

  • alter session enable parallel dml; 并行hint联合使用示例:
sql> alter session enable parallel dml;
session altered.
elapsed: 00:00:00.01
sql> update /*  parallel(4) */ t1 set object_name='cuihua1';
4917312 rows updated.
elapsed: 00:01:31.87
-- 执行计划:
sql> select * from table(dbms_xplan.display_cursor(null,null,'advanced'));
sql_id  2wajx9wh66udc, child number 0
-------------------------------------
 update /*  parallel(4) */ t1 set object_name='cuihua1'
plan hash value: 3991856572
---------------------------------------------------------------------------------------------------------------
| id  | operation             | name     | rows  | bytes | cost (%cpu)| time     |    tq  |in-out| pq distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | update statement      |          |       |       |  5271 (100)|          |        |      |            |
|   1 |  px coordinator       |          |       |       |            |          |        |      |            |
|   2 |   px send qc (random) | :tq10000 |  4785k|   301m|  5271   (1)| 00:01:04 |  q1,00 | p->s | qc (rand)  |
|   3 |    update             | t1       |       |       |            |          |  q1,00 | pcwp |            |
|   4 |     px block iterator |          |  4785k|   301m|  5271   (1)| 00:01:04 |  q1,00 | pcwc |            |
|*  5 |      table access full| t1       |  4785k|   301m|  5271   (1)| 00:01:04 |  q1,00 | pcwp |            |
---------------------------------------------------------------------------------------------------------------

未完待续

问答榜上引发的oracle并行的探究(二): https://www.modb.pro/db/521304

                   文章推荐

oracle: url
《oracle 自动收集统计信息机制》 https://www.modb.pro/db/403670
《oracle_索引重建—优化索引碎片》 https://www.modb.pro/db/399543
《dba_tab_modifications表的刷新策略测试》 https://www.modb.pro/db/414692
《fy_recover_data.dbf》 https://www.modb.pro/doc/74682
《oracle rac 集群迁移文件操作.pdf》 https://www.modb.pro/doc/72985
《oracle date 字段索引使用测试.dbf》 https://www.modb.pro/doc/72521
《oracle 诊断案例 :因应用死循环导致的cpu过高》 https://www.modb.pro/db/483047
《oracle 慢sql监控脚本》 https://www.modb.pro/db/479620
《oracle 慢sql监控测试及监控脚本.pdf》 https://www.modb.pro/doc/76068
《oracle 脚本实现简单的审计功能》 https://www.modb.pro/db/450052
《记录一起索引rebuild与收集统计信息的事故》 https://www.modb.pro/db/408934
《rac dg删除备库redo时报ora-01623》 https://www.modb.pro/db/515939
《ash报告发现:os thread startup 等待事件分析》 https://www.modb.pro/db/521146
《问答榜上引发的oracle并行的探究(一)》 https://www.modb.pro/db/521260
《问答榜上引发的oracle并行的探究(二)》 https://www.modb.pro/db/521304
                   欢迎赞赏支持或留言指正
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
1人已赞赏
z
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

网站地图