Oracle并行执行——parallel关键字的使用

前言

本篇文章主要对parallel关键字的使用进行介绍,内容包括parallel的作用、使用方式以及并行度过高的弊端等。希望对各位读者有所帮助

(一)parallel的作用

并行处理的机制实际上就是把一个要扫描的数据集分成很多小数据集,Oracle会启动几个并行服务进程同时处理这些小数据集,最后将这些结果汇总,作为最终的处理结果返回给用户。需要注意的是,使用parallel启动并发执行虽然高效,但本身也是有资源消耗的,如果只是小数据量的操作,即使用了parallel性能可能也没什么提升。

(二) 怎么确定parallel值的大小

一般来说,参与到并发计算的资源肯定是越多越好,但具体数值定多少合适呢?当数值高到一定程度其实性能是不会有什么提升的,我们可以通过下面的语句先来了解当前数据库和服务器的实际情况,从而选择合适的并发数。

  • 查看默认的并行值
    通过下面的语句,我们可以看到当前数据库的cpu数量以及每个cpu上面的线程数
show parameter cpu

一般来说,单实例的oracle应用,parallel默认的并发数为:cpu_count * parallel_thread_per_cpu(也就是cpu的数量乘cpu的线程数),网上也没有对这个数值大小有一个比较合理的说法,个人建议是最多到默认值的2-3倍就行了。

(三)parallel的使用

parallel关键字可以在DQL/DML/DDL语句中使用,可以说使用范围比较广泛了。这个关键字在不同类型语句中的使用方式略有不同,下面我们会对具体的使用展开介绍。

(1)对于DQL语句

对于查询语句,有三种方式可以开启并发查询,分别是hint方式、改变session方式和修改对象并行度方式

方式一:hint方式

格式:/*+ parallel(table_short_name,cash_number) */
table_short_name:表的别名,不区分大小写;cash_number是并发值

select /*+ parallel(t,10) */  count(*) from table1 t;
ps:

①如果直接使用/*+ parallel */的话,其实也会代入默认值触发并行查询,但具体的默认值怎么取值笔者不太确定。
②如果是多表查询的话,可以用类似这种写法来实现多表的并行度查询:/*+parallel(t,10) (b,10)*/
③如果是单表查询的话,使用/*+ parallel(10) */这种简写写法也是可行的

方式二:修改session方式

执行下面的方式后,后续所有的查询都会以当前会话设置的并发值来进行查询,下面的语句含义就是将当前会话涉及的查询语句并发值设置为4。

ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;
方式三:修改对象并行度方式

如果自己只会对少数表进行查询操作,也可以考虑通过直接修改表对象的并行度来加速查询。像下面的sql语句,就是修改了表对象的并发度,这样对表的所有操作都会以这个并行度去执行。

ALTER TABLE TB_NAME PARALLEL 4;

操作结束后,最好将表并行度给还原回去,避免占用系统资源

ALTER TABLE TB_NAME NOPARALLEL;

三种查询方式的优先度:Hint > session > object

(2) 对于DML语句

对于DML语句,其实和DQL语句类似,也有hint、session、object三种方式来启动并行执行

方式一:hint方式

其实,这里和DQL类似,就是在deleteupdateinsert关键字后面加入/*+ parallel(table_short_name,cash_number) */来并行执行,下面是例子:

DELETE /*+ parallel(8) */FROM TABLE1 WHERE ID > 3000 
UPDATE /*+ parallel(8) */ TABLE1 SET NAME = 'XXX' WHERE ID = 'XXX' 
INSERT /*+ parallel(8) */ INTO TABLE2  SELECT * FROM TABLE1 
方式二:修改session方式

执行下面的方式后,后续所有的DML操作都会以当前会话设置的并发值来进行执行,下面的语句含义就是将当前会话涉及的DML语句并发值设置为4。

alter session force parallel DML parallel 4;
方式三:修改object方式

这里其实和dql语句的处理方式一样,也是直接改表对象并行值就行。

ALTER TABLE TB_NAME PARALLEL 4;
(3)对于DDL语句

对于DDL语句,只有hint和session两种方式来并行执行

方式一:hint方式

这里的用法和dml、dql稍有不同,不需要再用/**/包裹parallel关键字了,直接用parallel 并发数值即可,一般是加在sql语句的最后,不过如果sql语句包含as的话,就要放在as的前面。具体使用案例可以看下面的例子:

CREATE TABLE table2 PARALLEL 8 AS SELECT * FROM table1
CREATE INDEX INDEX_NAME ON TABLE_NAME (COLUMN_NAME) PARALLEL 8 
ALTER TABLE table1 ADD column1 VARCHAR2(100) PARALLEL 8;
方式二:修改session方式
alter session force parallel DDL parallel n;

两种执行方式的优先度:hint方式 > session方式

(四)并行的弊端

诚然,开启并行处理的好处是十分明显的,能最大程度的调用系统资源来处理当前的请求。但是并行不是解决一切的银弹,如果是在DDL语句使用了parallel进行并行处理,则索引或表后续可能就会被设置为并行处理,这样当对表/索引数据进行查询的时候,也就都会进行并行处理,这样原本一条sql的执行可能就会占用到多个cpu,当数据库请求并发量大的时候,很容易出现资源的争抢导致执行速度反而变慢。
所以在使用完parallel去执行一些DDL语句后,建议是使用ALTER TABLE TABLE_NAME NOPARALLEL来关闭一下并行的使用。

(五)怎么查看当前所有表的并行度

前面提到,过度使用并行并不是好事,我们可以通过dba_tablesuser_tables来查看(一般来说生产环境我们是没有dba_tables表的查看权限的,所以更多时候我们是用user_tables来查看)当前所属表有没有并行度过高的情况,有的话要考虑及时关闭。

SELECT TABLE_NAME ,degree FROM USER_TABLES ORDER BY DEGREE desc ;
SELECT TABLE_NAME ,degree FROM DBA_TABLES WHERE OWNER = 'XXX' AND TABLESPACE_NAME= 'XXX' ORDER BY DEGREE desc 

(六) 怎么确定有没有parallel有没有生效呢?

我们在数据库连接工具中,观察sql语句的执行计划来进行确认
对于执行计划的查询方式,可以看我的这篇文章oracle怎么查看执行计划

从下文的执行计划中我们可以看到,加了parallel的sql语句执行计划确实发生了变化,多了数据分发、汇总这些操作


但上面的执行结果并不能反馈出当前执行具体用了多少并行度,如果希望看到这个结果,建议使用set autotrace on来打开这个信息的输出。

(网上其他文章有提到可以使用v$session视图来查看,但不知道是不是版本原因,我没有从这个视图里面找到能够观察是否并行执行的证据)

参考文章:
Oracle parallel理解:https://www.cnblogs.com/bicewow/p/14917096.html
Oracle笔记 之 并行(parallel)操作(DQL,DML,DDL):https://blog.csdn.net/weixin_50648794/article/details/113578536

posted @ 2023-10-08 19:36  moutory  阅读(2838)  评论(0编辑  收藏  举报  来源