我可以在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提示不会影响在查询中添加联合子句

提示独立应用于每个选择。首先,您需要了解并行执行在会话级别和/或应用的提示方面是如何工作的。

在这个你有三个元素

  • merge语句本身将更新一些行,并且不会并行运行
  • 第一次选择的第一个数据集恢复将并行运行
  • 由于对第一条语句应用了提示,第二条语句将并行运行

我假设这些表是用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

现在,我将构建一个merge语句,使用基于联合选择的源来更新表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

以下是执行计划中最重要的部分:

  • 由于表中没有统计数据,Oracle使用了动态采样
  • 由于hing而在4中使用的度数
  • 没有在会话级别启用并行DML,因此合并产生的更新在noparallel中运行
  • Oracle动态构建了一个VIEW来连接联盟的两个数据集,因为其中一个数据集是并行运行的,即使没有提示,CBO也会并行运行第二个数据集
  • 在USE_HASH提示中,始终使用较小的表作为驱动表。通常情况下,CBO总是这样做,所以我建议小心使用use_HASH提示,因为如果较小的表增长到比第二个表更大的点,那么您的提示将导致大量性能下降

希望它能澄清。