July 2010
M T W T F S S
« Jun    
 1234
567891011
12131415161718
19202122232425
262728293031  

如何决定Hash Partitions的数目

Kaya 发表于 os2ora.com

Hash也许是计算机科学里的一个重大发明,简单地说,Hash函数实现把一个值映射到相应的buckets里。而Hash函数也在数据仓库领域发挥着举足轻重的作用。

Teradata,一个专注于数据仓库应用的数据库。把并行发挥到极致,它的哲学就在于把任何一个操作都并行化。而并行的基础就在于对数据的Hash分布,通过Hash,实现数据的均匀分布,从而使得并行处理的各个进程能够分担大约相等的任务。

同样地,Oracle也广泛地使用着Hash算法,Hash Partitioning就是在数据仓库应用中的一个典型例子。Hash Partitioning的一个最大的优势就是实现partition wise join.

一个要考虑的问题在于hash partitions数目的选择,一个总的原则是它应该是2的乘方,如4,8,16,32,64,128…

另一个要考虑的方面在于硬件的处理能力,对了,就是RAC里面的节点数,还有每个节点CPU Cores的多少。说得再具体一点,就是默认的DOP的大小(默认DOP = 2 * cpu_count * number of nodes in the cluster)。一般而言,把hash partitions的个数设置成默认的DOP是一个推荐的设置值。在这种问题下,CBO一般会找到最好的执行计划,如利用partition-wise join的特性。

下面的执行计划是一个示例,这是一个利用了parition-wise join的例子。这里,DOP的大小等于hash partitions的个数。

---------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |          | 99999 |   976K|   128  (10)| 00:00:02 |       |       |        |      |            |
|   1 |  PX COORDINATOR         |          |       |       |            |          |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)   | :TQ10000 | 99999 |   976K|   128  (10)| 00:00:02 |       |       |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX PARTITION HASH ALL|          | 99999 |   976K|   128  (10)| 00:00:02 |     1 |     4 |  Q1,00 | PCWC |            |
|*  4 |     HASH JOIN           |          | 99999 |   976K|   128  (10)| 00:00:02 |       |       |  Q1,00 | PCWP |            |
|   5 |      TABLE ACCESS FULL  | FACT_B   | 99999 |   488K|    12   (9)| 00:00:01 |     1 |     4 |  Q1,00 | PCWP |            |
|   6 |      TABLE ACCESS FULL  | FACT_A   |   995K|  4860K|   112   (7)| 00:00:02 |     1 |     4 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------
Predicate Information (IDENTIFIED BY operation id):
---------------------------------------------------
   4 - access("A"."PART_COL1"="B"."PART_COL1")

如果hash partitions的个数比DOP还小,可能会出现下面的执行计划:

-------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          | 99999 |   976K|    64  (10)| 00:00:01 |       |       |        |      |            |
|   1 |  PX COORDINATOR             |          |       |       |            |          |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)       | :TQ10001 | 99999 |   976K|    64  (10)| 00:00:01 |       |       |  Q1,01 | P->S | QC (RAND)  |
|*  3 |    HASH JOIN                |          | 99999 |   976K|    64  (10)| 00:00:01 |       |       |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE              |          | 99999 |   488K|     6  (17)| 00:00:01 |       |       |  Q1,01 | PCWP |            |
|   5 |      PX SEND BROADCAST LOCAL| :TQ10000 | 99999 |   488K|     6  (17)| 00:00:01 |       |       |  Q1,00 | P->P | BCST LOCAL |
|   6 |       PX BLOCK ITERATOR     |          | 99999 |   488K|     6  (17)| 00:00:01 |     1 |     4 |  Q1,00 | PCWC |            |
|   7 |        TABLE ACCESS FULL    | FACT_B   | 99999 |   488K|     6  (17)| 00:00:01 |     1 |     4 |  Q1,00 | PCWP |            |
|   8 |     PX BLOCK ITERATOR       |          |   995K|  4860K|    56   (6)| 00:00:01 |     1 |     4 |  Q1,01 | PCWC |            |
|   9 |      TABLE ACCESS FULL      | FACT_A   |   995K|  4860K|    56   (6)| 00:00:01 |     1 |     4 |  Q1,01 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (IDENTIFIED BY operation id):
---------------------------------------------------
   3 - access("A"."PART_COL1"="B"."PART_COL1")

如果hash partitions的个数比DOP还大,可能会出现下面的执行计划:

--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          | 99999 |   976K|   256  (10)| 00:00:04 |       |       |        |      |            |
|   1 |  PX COORDINATOR              |          |       |       |            |          |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)        | :TQ10001 | 99999 |   976K|   256  (10)| 00:00:04 |       |       |  Q1,01 | P->S | QC (RAND)  |
|*  3 |    HASH JOIN                 |          | 99999 |   976K|   256  (10)| 00:00:04 |       |       |  Q1,01 | PCWP |            |
|   4 |     PX BLOCK ITERATOR        |          | 99999 |   488K|    23   (5)| 00:00:01 |     1 |     4 |  Q1,01 | PCWC |            |
|   5 |      TABLE ACCESS FULL       | FACT_B   | 99999 |   488K|    23   (5)| 00:00:01 |     1 |     4 |  Q1,01 | PCWP |            |
|   6 |     BUFFER SORT              |          |       |       |            |          |       |       |  Q1,01 | PCWC |            |
|   7 |      PX RECEIVE              |          |   995K|  4860K|   224   (6)| 00:00:03 |       |       |  Q1,01 | PCWP |            |
|   8 |       PX SEND BROADCAST LOCAL| :TQ10000 |   995K|  4860K|   224   (6)| 00:00:03 |       |       |  Q1,00 | P->P | BCST LOCAL |
|   9 |        PX BLOCK ITERATOR     |          |   995K|  4860K|   224   (6)| 00:00:03 |     1 |     4 |  Q1,00 | PCWC |            |
|  10 |         TABLE ACCESS FULL    | FACT_A   |   995K|  4860K|   224   (6)| 00:00:03 |     1 |     4 |  Q1,00 | PCWP |            |
--------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (IDENTIFIED BY operation id):
---------------------------------------------------
   3 - access("A"."PART_COL1"="B"."PART_COL1")

如果hash partitions的个数与默认的DOP一致,那当然可以节省很多时间,如果不是呢,而且要修改Hash Partitions的个数其实不是一件很容易的事情,那就只能通过调整DOP来得到一个好的执行计划了。两种方法:

  • 在表一级,通过 alter table parallel <degree>
  • 在SQL一级,通过/*+ parallel (table_name, <degree> */

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">