现有如下 SQL。

    1. select * from a,b where a.object_id=b.object_id;

    表 a 有 30MB,表 b 有 30GB,两表关联后返回大量数据,应该走 HASH 连接,因为 a 是小表所以 a 应该作为 HASH JOIN 的驱动表,大表 b 作为 HASH JOIN 的被驱动表。在进行 HASH JOIN 的时候,驱动表会被放到 PGA 中,这里,因为驱动表 a 只有 30MB,PGA 能够完全容纳下驱动表。因为被驱动表 b 特别大,想要加快 SQL 查询速度,必须开启并行查询。超大表与超小表在进行并行 HASH 连接的时候,可以将小表(驱动表)广播到所有的查询进程,然后对大表进行并行随机扫描,每个查询进程查询部分 b 表数据,然后再进行关联。假设对以上 SQL 启用 6 个并行进程对 a 表的并行广播,对 b 表进行随机并行扫描(每部分记为 b1,b2,b3,b4,b5,b6)其实就相当于将以上 SQL 内部等价改写为下面 SQL。

    1. select * from ab1 where a.object_id=b1.object_id ---并行进行
    2. union all
    3. select * from ab2 where a.object_id=b2.object_id ---并行进行
    4. union all
    5. select * from ab3 where a.object_id=b3.object_id ---并行进行
    6. union all
    7. select * from ab4 where a.object_id=b4.object_id ---并行进行
    8. union all
    9. select * from ab5 where a.object_id=b5.object_id ---并行进行
    10. union all
    11. select * from ab6 where a.object_id=b6.object_id ---并行进行

    怎么才能让 a 表进行广播呢?我们需要添加hint:**pq_distribute(驱动表 none,broadcast)**

    现在我们来查看 a 表并行广播的执行计划(为了方便排版,执行计划中省略了部分数据)。

    1. explain plan for select
    2. /*+ parallel(6) use_hash(a,b) pq_distribute(a none,broadcast) */
    3. *
    4. from a, b
    5. where a.object_id = b.object_id;
    1. Explained.
    1. select * from table(dbms_xplan.display);
    1. PLAN_TABLE_OUTPUT
    2. -----------------------------------------------------------------------------------
    3. Plan hash value: 3536517442
    4. --------------------------------------------------------------------------------
    5. | Id | Operation | Name | Rows | Bytes |IN-OUT| PQ Distrib |
    6. --------------------------------------------------------------------------------
    7. | 0 | SELECT STATEMENT | | 5064K| 1999M| | |
    8. | 1 | PX COORDINATOR | | | | | |
    9. | 2 | PX SEND QC (RANDOM) | :TQ10001 | 5064K| 1999M| P->S | QC (RAND) |
    10. |* 3 | HASH JOIN | | 5064K| 1999M| PCWP | |
    11. | 4 | PX RECEIVE | | 74893 | 14M| PCWP | |
    12. | 5 | PX SEND BROADCAST | :TQ10000 | 74893 | 14M| P->P | BROADCAST |
    13. | 6 | PX BLOCK ITERATOR | | 74893 | 14M| PCWC | |
    14. | 7 | TABLE ACCESS FULL| A | 74893 | 14M| PCWP | |
    15. | 8 | PX BLOCK ITERATOR | | 5064K| 999M| PCWC | |
    16. | 9 | TABLE ACCESS FULL | B | 5064K| 999M| PCWP | |
    17. --------------------------------------------------------------------------------
    18. Predicate Information (identified by operation id):
    19. ---------------------------------------------------
    20. 3 - access("A"."OBJECT_ID"="B"."OBJECT_ID")

    如果小表进行了广播,执行计划 Operation 会出现 PX SEND BROADCAST 关键字PQ Distrib 会出现 BROADCAST 关键字。注意:如果是两个大表关联,千万不能让大表广播。