暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 没有任何并行提示或并行度的并行DML更新

askTom 2017-10-16
369

问题描述

大家好,

在我们的生产环境中,一个DML更新并行运行,并且本质上是零星的。
请注意,会话已为并行dml启用。

在下面找到该更新语句的一个伪代码。

---------------
ALTER SESSION ENABLE PARALLEL DML;

UPDATE TABLE_1 A
SET 
  A.COLUMN_1 =
       (SELECT COUNT(*)
        FROM TABLE_2 B
        WHERE B.KEY_COL = A.KEY_COL)
WHERE 
 A.KEY_COL IN
  (SELECT DISTINCT KEY_COL FROM TABLE_2)
复制

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

TABLE_1 (目标表和分区) 的并行度设置为1
TABLE_2的平行度 (在谓词中使用) 设置为默认值 (16)
数据库版本-11.2.0.4.0

-----------

并行自适应多用户 = FALSE
平行 _ 度 _ 极限 = 16
平行 _ 程度 _ 策略 = 自动
parallel_force_local FALSE
----------

我的理解是,如果我们不添加并行提示 (更新/* 并行 */),并且将目标表的度数设置为1,那么DML更新将不会并行执行,尽管会话为并行DML启用。

您能告诉我我的理解是否正确吗?

感谢你的帮助。

专家解答

不完全是...

您的SQL有两个部分:

-更新
-访问另一个表的查询

优化器可以并行化两者或仅是查询而不是更新。

如果您将parallel_degree_policy设置为手动或受限,则优化器将根据表设置或提示选择并行性。

这里我们有目标表的并行1和源的并行2。所以查询是解析的,但不是更新:

alter session enable parallel dml;
alter session enable parallel query;
alter session set statistics_level = all;
set serveroutput off
create table t1 (x) as 
  select rownum x from dual
  connect by level <= 10000;
create table t2 (x) as 
  select rownum x from dual
  connect by level <= 10000;
alter table t2 parallel ;

exec dbms_stats.gather_table_stats(user, 'T1');
exec dbms_stats.gather_table_stats(user, 'T2');

alter session set parallel_degree_policy = manual;

update t1
set   x = (
  select count(*) from t2
);

select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST +PARALLEL +NOTE'));

PLAN_TABLE_OUTPUT                                                           
EXPLAINED SQL STATEMENT:                                                    
------------------------                                                    
update t1 set   x = (   select count(*) from t2 )                           
                                                                            
Plan hash value: 3079932949                                                 
                                                                            
-------------------------------------------------------------------------   
| Id  | Operation               | Name     |    TQ  |IN-OUT| PQ Distrib |   
-------------------------------------------------------------------------   
|   0 | UPDATE STATEMENT        |          |        |      |            |   
|   1 |  UPDATE                 | T1       |        |      |            |   
|   2 |   TABLE ACCESS FULL     | T1       |        |      |            |   
|   3 |   SORT AGGREGATE        |          |        |      |            |   
|   4 |    PX COORDINATOR       |          |        |      |            |   
|   5 |     PX SEND QC (RANDOM) | :TQ10000 |  Q1,00 | P->S | QC (RAND)  |   
|   6 |      SORT AGGREGATE     |          |  Q1,00 | PCWP |            |   
|   7 |       PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            |   
|   8 |        TABLE ACCESS FULL| T2       |  Q1,00 | PCWP |            |   
-------------------------------------------------------------------------   
                                                                            
Note                                                                        
-----                                                                       
   - PDML disabled because object is not decorated with parallel clause     

commit;
复制


但是你也有parallel_degre_policy = auto。所以数据库会自动确定适当的并行度。这将覆盖您设置为表的并行级别的任何内容:

alter session set parallel_degree_policy = auto;
  
update t1
set   x = (
  select count(*) from t2
);

select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST +PARALLEL +NOTE'));

PLAN_TABLE_OUTPUT                                                                       
EXPLAINED SQL STATEMENT:                                                                
------------------------                                                                
update t1 set   x = (   select count(*) from t2 )                                       
                                                                                        
Plan hash value: 2278366140                                                             
                                                                                        
------------------------------------                                                    
| Id  | Operation           | Name |                                                    
------------------------------------                                                    
|   0 | UPDATE STATEMENT    |      |                                                    
|   1 |  UPDATE             | T1   |                                                    
|   2 |   TABLE ACCESS FULL | T1   |                                                    
|   3 |   SORT AGGREGATE    |      |                                                    
|   4 |    TABLE ACCESS FULL| T2   |                                                    
------------------------------------                                                    
                                                                                        
Note                                                                                    
-----                                                                                   
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold   
   - PDML disabled because object is not decorated with parallel clause                 

commit;

alter table t1 parallel 2;
update t1
set   x = (
  select count(*) from t2
);

select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST +PARALLEL +NOTE'));

PLAN_TABLE_OUTPUT                                                                       
EXPLAINED SQL STATEMENT:                                                                
------------------------                                                                
update t1 set   x = (   select count(*) from t2 )                                       
                                                                                        
Plan hash value: 2278366140                                                             
                                                                                        
------------------------------------                                                    
| Id  | Operation           | Name |                                                    
------------------------------------                                                    
|   0 | UPDATE STATEMENT    |      |                                                    
|   1 |  UPDATE             | T1   |                                                    
|   2 |   TABLE ACCESS FULL | T1   |                                                    
|   3 |   SORT AGGREGATE    |      |                                                    
|   4 |    TABLE ACCESS FULL| T2   |                                                    
------------------------------------                                                    
                                                                                        
Note                                                                                    
-----                                                                                   
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold   
   - PDML disabled because object is not decorated with parallel clause                 

commit;
复制


如果您的表变得足够大,或者您降低了足够低的并行化阈值 (默认为10s),那么数据库将为您选择并行性级别。

让我们将阈值降低到1s,并通过将统计信息设置为10亿行来使表看起来很大:

alter session set parallel_min_time_threshold = 1;
exec dbms_stats.set_table_stats( user, 'T1' , numrows => 1000000000, numblks => 1000000 );
update t1
set   x = (
  select count(*) from t2
);

select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST +PARALLEL +NOTE'));

PLAN_TABLE_OUTPUT                                                                 
EXPLAINED SQL STATEMENT:                                                          
------------------------                                                          
update t1 set   x = (   select count(*) from t2 )                                 
                                                                                  
Plan hash value: 4037313505                                                       
                                                                                  
-----------------------------------------------------------------------           
| Id  | Operation             | Name     |    TQ  |IN-OUT| PQ Distrib |           
-----------------------------------------------------------------------           
|   0 | UPDATE STATEMENT      |          |        |      |            |           
|   1 |  PX COORDINATOR       |          |        |      |            |           
|   2 |   PX SEND QC (RANDOM) | :TQ10000 |  Q1,00 | P->S | QC (RAND)  |           
|   3 |    UPDATE             | T1       |  Q1,00 | PCWP |            |           
|   4 |     PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            |           
|   5 |      TABLE ACCESS FULL| T1       |  Q1,00 | PCWP |            |           
|   6 |     SORT AGGREGATE    |          |        |      |            |           
|   7 |      TABLE ACCESS FULL| T2       |        |      |            |           
-----------------------------------------------------------------------           
                                                                                  
Note                                                                              
-----                                                                             
   - automatic DOP: Computed Degree of Parallelism is 4 because of degree limit   
 
commit;
复制


在这种情况下,优化器选择了4的平行度。

要使用特定级别的并行性,您需要使用提示:

update /*+ parallel (2) */t1
set   x = (
  select count(*) from t2
);

select * from table(dbms_xplan.display_cursor(null, null, 'BASIC LAST +PARALLEL +NOTE'));

PLAN_TABLE_OUTPUT                                                         
EXPLAINED SQL STATEMENT:                                                  
------------------------                                                  
update /*+ parallel (2) */t1 set   x = (   select count(*) from t2 )      
                                                                          
Plan hash value: 4037313505                                               
                                                                          
-----------------------------------------------------------------------   
| Id  | Operation             | Name     |    TQ  |IN-OUT| PQ Distrib |   
-----------------------------------------------------------------------   
|   0 | UPDATE STATEMENT      |          |        |      |            |   
|   1 |  PX COORDINATOR       |          |        |      |            |   
|   2 |   PX SEND QC (RANDOM) | :TQ10000 |  Q1,00 | P->S | QC (RAND)  |   
|   3 |    UPDATE             | T1       |  Q1,00 | PCWP |            |   
|   4 |     PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            |   
|   5 |      TABLE ACCESS FULL| T1       |  Q1,00 | PCWP |            |   
|   6 |     SORT AGGREGATE    |          |        |      |            |   
|   7 |      TABLE ACCESS FULL| T2       |        |      |            |   
-----------------------------------------------------------------------   
                                                                          
Note                                                                      
-----                                                                     
   - Degree of Parallelism is 2 because of hint

commit;
复制


在以下位置阅读有关自动并行性的更多信息:

https://blogs.oracle.com/datawarehousing/what-is-auto-dop
https://blogs.oracle.com/datawarehousing/configuring-and-controlling-auto-dop
https://blogs.oracle.com/datawarehousing/optimizer-processing-rates-for-auto-dop
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论