我可以在 oracle 的一个联合子句中使用不同的提示吗
can I use different hints in one clause of union in oracle
我有以下格式的合并查询 -
merge into dest
using (select /*+ use_hash(t1,t2) parallel (4)*/ t1_name ,count(*) from table1 , table2 on t1.col=t2.col
group by t1_name) src
on (values)
when matched then update dest.col
现在我必须在这个查询中做并集
merge into dest
using (select count(*),t1_name from (select /*+ use_hash(t1,t2) parallel (4)*/ t1_name ,count(*) from table1 , table2 on t1.col=t2.col
group by t1_name
union all
select t1_name,count(*) from table t1 group by t1_name from table t1 group by t1_name ) group by t1_name) src
on (values)
when matched then update dest.col
我的问题是我是否也必须在第二个并集子句中给出平行提示。另外 use_hash 之前 运行 好的提示不会对在查询中添加联合子句产生影响
提示独立适用于每个 select。首先,您需要了解并行执行如何在会话级别 and/or 应用的提示方面工作。
这里有三个元素
- 合并语句本身会更新一些行,不会 运行 并行
- 第一个数据集与第一个 select 并行恢复 运行
- 由于提示应用于第一个语句
,第二个将 运行 并行
我假设 table 配置了 noparallel,并且您没有启用并行 dml。我什至不会尝试复制查询,因为我不知道你想用它做什么。
测试用例
SQL> create table t1 ( c1 number, c2 number ) ;
Table created.
SQL> create table t2 ( c1 number, c3 number ) ;
Table created.
SQL> ed
Wrote file afiedt.buf
1 declare
2 begin
3 for i in 1 .. 10000
4 loop
5 insert into t1 values ( i , dbms_random.value );
6 insert into t2 values ( i , dbms_random.value );
7 end loop;
8* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> ed
Wrote file afiedt.buf
1 declare
2 begin
3 for i in 1 .. 10000
4 loop
5 insert into t1 values ( i , dbms_random.value );
6 end loop;
7* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> select count(*) from t1 ;
COUNT(*)
----------
20000
SQL> select count(*) from t2 ;
COUNT(*)
----------
10000
现在我将构建一个合并语句来使用基于联合 select 的源更新 table t2。忘记这种情况下查询的意义,完全没有意义,但是得到的执行计划
SQL> merge into t dest
2 using ( select distinct t1 from (
3 select /*+ use_hash(t2,t1) parallel (4)*/ t1.c1 as t1 from t1 inner join t2 on ( t1.c1=t2.c1)
4 union all
5 select t2.c1 as t1 from t1 inner join t2 on ( t1.c1=t2.c1 )
6 )) src on ( src.t1 = dest.c1 )
7* when matched then update set dest.c2 = dbms_random.value
10000 rows merged.
Execution Plan
----------------------------------------------------------
Plan hash value: 889987475
-----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 10000 | 253K| 43 (3)| 00:00:01 | | | |
| 1 | MERGE | T | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10006 | 10000 | 498K| 43 (3)| 00:00:01 | Q1,06 | P->S | QC (RAND) |
| 4 | VIEW | | | | | | Q1,06 | PCWP | |
|* 5 | HASH JOIN | | 10000 | 498K| 43 (3)| 00:00:01 | Q1,06 | PCWP | |
| 6 | PX RECEIVE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,06 | PCWP | |
| 7 | PX SEND BROADCAST | :TQ10005 | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | P->P | BROADCAST |
| 8 | VIEW | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 9 | HASH UNIQUE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 10 | PX RECEIVE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 11 | PX SEND HASH | :TQ10004 | 10000 | 126K| 17 (6)| 00:00:01 | Q1,04 | P->P | HASH |
| 12 | HASH UNIQUE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,04 | PCWP | |
| 13 | VIEW | | 40000 | 507K| 16 (0)| 00:00:01 | Q1,04 | PCWP | |
| 14 | UNION-ALL | | | | | | Q1,04 | PCWP | |
|* 15 | HASH JOIN | | 20000 | 507K| 8 (0)| 00:00:01 | Q1,04 | PCWP | |
| 16 | PX RECEIVE | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,04 | PCWP | |
| 17 | PX SEND HASH | :TQ10000 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | P->P | HASH |
| 18 | PX BLOCK ITERATOR | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | PCWC | |
| 19 | TABLE ACCESS FULL| T2 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | PCWP | |
| 20 | PX RECEIVE | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,04 | PCWP | |
| 21 | PX SEND HASH | :TQ10001 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | P->P | HASH |
| 22 | PX BLOCK ITERATOR | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | PCWC | |
| 23 | TABLE ACCESS FULL| T1 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | PCWP | |
|* 24 | HASH JOIN | | 20000 | 507K| 8 (0)| 00:00:01 | Q1,04 | PCWP | |
| 25 | PX RECEIVE | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,04 | PCWP | |
| 26 | PX SEND HASH | :TQ10002 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | P->P | HASH |
| 27 | PX BLOCK ITERATOR | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | PCWC | |
| 28 | TABLE ACCESS FULL| T2 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | PCWP | |
| 29 | PX RECEIVE | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,04 | PCWP | |
| 30 | PX SEND HASH | :TQ10003 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | P->P | HASH |
| 31 | PX BLOCK ITERATOR | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | PCWC | |
| 32 | TABLE ACCESS FULL| T1 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | PCWP | |
| 33 | PX BLOCK ITERATOR | | 94911 | 3522K| 26 (0)| 00:00:01 | Q1,06 | PCWC | |
| 34 | TABLE ACCESS FULL | T | 94911 | 3522K| 26 (0)| 00:00:01 | Q1,06 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("SRC"."T1"="DEST"."C1")
15 - access("T1"."C1"="T2"."C1")
24 - access("T1"."C1"="T2"."C1")
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of hint
- PDML is disabled in current session
以下执行计划中最重要的部分:
- 由于table没有统计信息,Oracle采用了动态抽样
- 4中因hing用的度数
- 并行 DML 未在会话级别启用,因此合并 运行s 的更新结果为非并行。
- Oracle 动态构建一个 VIEW 来连接 union 的两个数据集,因为其中一个是 运行ning 并行,CBO 运行s 是并行的,第二个甚至虽然它没有任何提示。
- 在 USE_HASH 提示中始终使用较小的 table 作为驱动 table。通常 CBO 总是这样做,所以我建议谨慎使用 USE_HASH 提示,因为如果较小的 table 增长到比第二个更大的点,您的提示将产生性能下降很多。
希望它澄清。
我有以下格式的合并查询 -
merge into dest
using (select /*+ use_hash(t1,t2) parallel (4)*/ t1_name ,count(*) from table1 , table2 on t1.col=t2.col
group by t1_name) src
on (values)
when matched then update dest.col
现在我必须在这个查询中做并集
merge into dest
using (select count(*),t1_name from (select /*+ use_hash(t1,t2) parallel (4)*/ t1_name ,count(*) from table1 , table2 on t1.col=t2.col
group by t1_name
union all
select t1_name,count(*) from table t1 group by t1_name from table t1 group by t1_name ) group by t1_name) src
on (values)
when matched then update dest.col
我的问题是我是否也必须在第二个并集子句中给出平行提示。另外 use_hash 之前 运行 好的提示不会对在查询中添加联合子句产生影响
提示独立适用于每个 select。首先,您需要了解并行执行如何在会话级别 and/or 应用的提示方面工作。
这里有三个元素
- 合并语句本身会更新一些行,不会 运行 并行
- 第一个数据集与第一个 select 并行恢复 运行
- 由于提示应用于第一个语句 ,第二个将 运行 并行
我假设 table 配置了 noparallel,并且您没有启用并行 dml。我什至不会尝试复制查询,因为我不知道你想用它做什么。
测试用例
SQL> create table t1 ( c1 number, c2 number ) ;
Table created.
SQL> create table t2 ( c1 number, c3 number ) ;
Table created.
SQL> ed
Wrote file afiedt.buf
1 declare
2 begin
3 for i in 1 .. 10000
4 loop
5 insert into t1 values ( i , dbms_random.value );
6 insert into t2 values ( i , dbms_random.value );
7 end loop;
8* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> ed
Wrote file afiedt.buf
1 declare
2 begin
3 for i in 1 .. 10000
4 loop
5 insert into t1 values ( i , dbms_random.value );
6 end loop;
7* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> select count(*) from t1 ;
COUNT(*)
----------
20000
SQL> select count(*) from t2 ;
COUNT(*)
----------
10000
现在我将构建一个合并语句来使用基于联合 select 的源更新 table t2。忘记这种情况下查询的意义,完全没有意义,但是得到的执行计划
SQL> merge into t dest
2 using ( select distinct t1 from (
3 select /*+ use_hash(t2,t1) parallel (4)*/ t1.c1 as t1 from t1 inner join t2 on ( t1.c1=t2.c1)
4 union all
5 select t2.c1 as t1 from t1 inner join t2 on ( t1.c1=t2.c1 )
6 )) src on ( src.t1 = dest.c1 )
7* when matched then update set dest.c2 = dbms_random.value
10000 rows merged.
Execution Plan
----------------------------------------------------------
Plan hash value: 889987475
-----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 10000 | 253K| 43 (3)| 00:00:01 | | | |
| 1 | MERGE | T | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10006 | 10000 | 498K| 43 (3)| 00:00:01 | Q1,06 | P->S | QC (RAND) |
| 4 | VIEW | | | | | | Q1,06 | PCWP | |
|* 5 | HASH JOIN | | 10000 | 498K| 43 (3)| 00:00:01 | Q1,06 | PCWP | |
| 6 | PX RECEIVE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,06 | PCWP | |
| 7 | PX SEND BROADCAST | :TQ10005 | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | P->P | BROADCAST |
| 8 | VIEW | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 9 | HASH UNIQUE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 10 | PX RECEIVE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,05 | PCWP | |
| 11 | PX SEND HASH | :TQ10004 | 10000 | 126K| 17 (6)| 00:00:01 | Q1,04 | P->P | HASH |
| 12 | HASH UNIQUE | | 10000 | 126K| 17 (6)| 00:00:01 | Q1,04 | PCWP | |
| 13 | VIEW | | 40000 | 507K| 16 (0)| 00:00:01 | Q1,04 | PCWP | |
| 14 | UNION-ALL | | | | | | Q1,04 | PCWP | |
|* 15 | HASH JOIN | | 20000 | 507K| 8 (0)| 00:00:01 | Q1,04 | PCWP | |
| 16 | PX RECEIVE | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,04 | PCWP | |
| 17 | PX SEND HASH | :TQ10000 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | P->P | HASH |
| 18 | PX BLOCK ITERATOR | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | PCWC | |
| 19 | TABLE ACCESS FULL| T2 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,00 | PCWP | |
| 20 | PX RECEIVE | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,04 | PCWP | |
| 21 | PX SEND HASH | :TQ10001 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | P->P | HASH |
| 22 | PX BLOCK ITERATOR | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | PCWC | |
| 23 | TABLE ACCESS FULL| T1 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,01 | PCWP | |
|* 24 | HASH JOIN | | 20000 | 507K| 8 (0)| 00:00:01 | Q1,04 | PCWP | |
| 25 | PX RECEIVE | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,04 | PCWP | |
| 26 | PX SEND HASH | :TQ10002 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | P->P | HASH |
| 27 | PX BLOCK ITERATOR | | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | PCWC | |
| 28 | TABLE ACCESS FULL| T2 | 10000 | 126K| 3 (0)| 00:00:01 | Q1,02 | PCWP | |
| 29 | PX RECEIVE | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,04 | PCWP | |
| 30 | PX SEND HASH | :TQ10003 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | P->P | HASH |
| 31 | PX BLOCK ITERATOR | | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | PCWC | |
| 32 | TABLE ACCESS FULL| T1 | 20000 | 253K| 5 (0)| 00:00:01 | Q1,03 | PCWP | |
| 33 | PX BLOCK ITERATOR | | 94911 | 3522K| 26 (0)| 00:00:01 | Q1,06 | PCWC | |
| 34 | TABLE ACCESS FULL | T | 94911 | 3522K| 26 (0)| 00:00:01 | Q1,06 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("SRC"."T1"="DEST"."C1")
15 - access("T1"."C1"="T2"."C1")
24 - access("T1"."C1"="T2"."C1")
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- Degree of Parallelism is 4 because of hint
- PDML is disabled in current session
以下执行计划中最重要的部分:
- 由于table没有统计信息,Oracle采用了动态抽样
- 4中因hing用的度数
- 并行 DML 未在会话级别启用,因此合并 运行s 的更新结果为非并行。
- Oracle 动态构建一个 VIEW 来连接 union 的两个数据集,因为其中一个是 运行ning 并行,CBO 运行s 是并行的,第二个甚至虽然它没有任何提示。
- 在 USE_HASH 提示中始终使用较小的 table 作为驱动 table。通常 CBO 总是这样做,所以我建议谨慎使用 USE_HASH 提示,因为如果较小的 table 增长到比第二个更大的点,您的提示将产生性能下降很多。
希望它澄清。