问题描述
大家好,
在我们的生产环境中,一个DML更新并行运行,并且本质上是零星的。
请注意,会话已为并行dml启用。
在下面找到该更新语句的一个伪代码。
---------------
------------
TABLE_1 (目标表和分区) 的并行度设置为1
TABLE_2的平行度 (在谓词中使用) 设置为默认值 (16)
数据库版本-11.2.0.4.0
-----------
并行自适应多用户 = FALSE
平行 _ 度 _ 极限 = 16
平行 _ 程度 _ 策略 = 自动
parallel_force_local FALSE
----------
我的理解是,如果我们不添加并行提示 (更新/* 并行 */),并且将目标表的度数设置为1,那么DML更新将不会并行执行,尽管会话为并行DML启用。
您能告诉我我的理解是否正确吗?
感谢你的帮助。
在我们的生产环境中,一个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。所以查询是解析的,但不是更新:
但是你也有parallel_degre_policy = auto。所以数据库会自动确定适当的并行度。这将覆盖您设置为表的并行级别的任何内容:
如果您的表变得足够大,或者您降低了足够低的并行化阈值 (默认为10s),那么数据库将为您选择并行性级别。
让我们将阈值降低到1s,并通过将统计信息设置为10亿行来使表看起来很大:
在这种情况下,优化器选择了4的平行度。
要使用特定级别的并行性,您需要使用提示:
在以下位置阅读有关自动并行性的更多信息:
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
您的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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle DataGuard高可用性解决方案详解
孙莹
522次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
499次阅读
2025-04-15 17:24:06
墨天轮个人数说知识点合集
JiekeXu
410次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
407次阅读
2025-04-08 09:12:48
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
391次阅读
2025-04-18 14:18:38
Oracle SQL 执行计划分析与优化指南
Digital Observer
389次阅读
2025-04-01 11:08:44
Oracle 19c RAC更换IP实战,运维必看!
szrsu
350次阅读
2025-04-08 23:57:08
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
343次阅读
2025-04-20 10:07:02
oracle定时任务常用攻略
virvle
320次阅读
2025-03-25 16:05:19
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
318次阅读
2025-04-15 14:48:05