日本語PDF

3.2 パーティション・ワイズ操作

パーティション・ワイズ操作により、レスポンス時間は大幅に短縮され、CPUとメモリー・リソースの使用率が改善されます。

パーティション・ワイズ結合では、結合がパラレルで実行されるときにパラレル実行サーバー間で交換されるデータ量が最小限に抑えられ、問合せのレスポンス時間が短縮されます。Oracle Real Application Clusters (Oracle RAC)環境では、パーティション・ワイズ結合でも、インターコネクトでのデータ・トラフィックが回避されるか、少なくとも制限されます。これは、大規模な結合操作で優れたスケーラビリティを実現するために重要です。パラレル・パーティション・ワイズ結合は、大きな結合を効率的かつ高速に処理するために一般的に使用されます。パーティション・ワイズ結合では、フル(完全)またはパーシャル(部分)を選択できます。どちらの種類の結合を使用するかはOracle Databaseによって判別されます。

パラレル・パーティション・ワイズ結合に加えて、SELECT DISTINCT句およびSQLウィンドウ関数を使用した問合せでは、パラレル・パーティション・ワイズ操作を実行できます。

次の内容について説明します。

関連項目:

3.2.1 フル・パーティション・ワイズ結合

フル・パーティション・ワイズ結合では、結合される2つの表の対のパーティション間で、大きな結合が小さな結合に分割されます。

フル・パーティション・ワイズ結合を使用するには、両方の表を結合キーで同一レベルでパーティション化するか、参照パーティション化を使用する必要があります。

2つの表を同一レベル・パーティション化するには様々なパーティション化方法を使用できます。これらの方法の概要を次のトピックで説明します。

3.2.1.1 フル・パーティション・ワイズ結合による問合せ

フル・パーティション・ワイズ結合を使用して問合せできます。

たとえば、例3-4に示すように、sales表とcustomer表の列cust_idによる大規模な結合について考えてみます。「1999年の第3四半期に品物の購入数が100を超えたすべての顧客のレコードを検索する」という問合せは、このような結合を実行するSQL文の典型的な例です。

このような大規模な結合は、データ・ウェアハウス環境ではよく行われます。この場合、customer表全体が1四半期分のsalesデータに結合されます。大規模なデータ・ウェアハウス・アプリケーションの場合には、数百万行の結合を意味することもあります。ここは明らかにハッシュ結合が使用されます。両方の表がcust_id列で同一レベル・パーティション化されている場合は、このハッシュ結合の処理時間をさらに短縮できます。この機能によりフル・パーティション・ワイズ結合が使用可能になります。

フル・パーティション・ワイズ結合をパラレルで実行するとき、パラレル化のグラニュルはパーティションです。このため、並列度はパーティション数に制限されます。たとえば、問合せの並列度を16に設定するには少なくとも16のパーティションが必要です。

例3-4 フル・パーティション・ワイズ結合による問合せ

SELECT c.cust_last_name, COUNT(*)
  FROM sales s, customers c
  WHERE s.cust_id = c.cust_id AND 
        s.time_id BETWEEN TO_DATE('01-JUL-1999', 'DD-MON-YYYY') AND 
        (TO_DATE('01-OCT-1999', 'DD-MON-YYYY'))
  GROUP BY c.cust_last_name HAVING COUNT(*) > 100;

3.2.1.2 フル・パーティション・ワイズ結合: 単一レベル-単一レベル

単一レベルから単一レベルへのフル・パーティション・ワイズ結合は、最も簡単な方法であり、2つの表は両方とも結合列によってパーティション化されます。

例では、customers表とsales表の両方がcust_id列でパーティション化されます。このパーティション化方法では、表をcust_id (両方とも同じ顧客ID番号を表す)で結合するフル・パーティション・ワイズ結合が有効になります。このシナリオは、レンジ - レンジ、リスト - リストおよびハッシュ - ハッシュ・パーティション化に対応します。時間隔 - レンジおよび時間隔 - 時間隔のフル・パーティション・ワイズ結合もサポートされ、レンジ - レンジと比較できます。

シリアルでは、この結合は、ハッシュ・パーティションの一致する組の間で、1回ずつ順番に実行されます。1組のパーティションが結合されると、別の組の結合が開始されます。すべてのパーティションの組が処理されると、結合が完了します。作業負荷を均等に分散するためには、要求した並列度よりも多数のパーティションを使用するか、要求した並列度と同数の同一サイズ・パーティションを使用する必要があります。同一サイズ・パーティションを作成するには、パーティション数を2の累乗として、一意の列(またはほぼ一意の列)に対してハッシュ・パーティション化を使用することをお薦めします。

ノート:

  • 一致する1組のハッシュ・パーティションは、同じパーティション番号を持つ各表のパーティションとして定義されています。たとえば、ハッシュ・パーティション化に基づくフル・パーティション・ワイズ結合では、salesのパーティション0とcustomersのパーティション0、salesのパーティション1とcustomersのパーティション1のように結合されます。

  • 参照パーティション化は、2つの表をともにパーティション化する簡単な方法です。これにより、文で表が結合される際に、オプティマイザがフル・パーティション・ワイズ結合を常に検討できるようになります。

フル・パーティション・ワイズ結合のパラレル実行は、シリアル実行を単にパラレル化したものです。パーティションが1組ずつ結合されるかわりに、問合せサーバーによってパーティションの複数の組がパラレルに結合されます。図3-1に、フル・パーティション・ワイズ結合のパラレル実行を示します。

図3-1 フル・パーティション・ワイズ結合のパラレル実行

図3-1の説明が続きます
「図3-1 フル・パーティション・ワイズ結合のパラレル実行」の説明

次の例は、同数のパーティションを含むようにハッシュで同等にパーティション化されたsalescustomersの実行計画を示します。この計画はフル・パーティション・ワイズ結合を示しています。

explain plan for SELECT c.cust_last_name, COUNT(*)
FROM sales s, customers c
WHERE s.cust_id = c.cust_id AND 
s.time_id BETWEEN TO_DATE('01-JUL-1999', 'DD-MON-YYYY') AND 
     (TO_DATE('01-OCT-1999', 'DD-MON-YYYY'))
GROUP BY c.cust_last_name HAVING COUNT(*) > 100;

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Pstart| Pstop|    TQ  |IN-OUT| PQ Distrib|
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    46 |  1196 |       |      |        |      |           |
|   1 |  PX COORDINATOR              |           |       |       |       |      |        |      |           |
|   2 |   PX SEND QC (RANDOM)        | :TQ10001  |    46 |  1196 |       |      |  Q1,01 | P->S | QC (RAND) |
|*  3 |    FILTER                    |           |       |       |       |      |  Q1,01 | PCWC |           |
|   4 |     HASH GROUP BY            |           |    46 |  1196 |       |      |  Q1,01 | PCWP |           |
|   5 |      PX RECEIVE              |           |    46 |  1196 |       |      |  Q1,01 | PCWP |           |
|   6 |       PX SEND HASH           | :TQ10000  |    46 |  1196 |       |      |  Q1,00 | P->P | HASH      |
|   7 |        HASH GROUP BY         |           |    46 |  1196 |       |      |  Q1,00 | PCWP |           |
|   8 |         PX PARTITION HASH ALL|           | 59158 |  1502K|     1 |   16 |  Q1,00 | PCWC |           |
|*  9 |          HASH JOIN           |           | 59158 |  1502K|       |      |  Q1,00 | PCWP |           |
|  10 |           TABLE ACCESS FULL  | CUSTOMERS | 55500 |   704K|     1 |   16 |  Q1,00 | PCWP |           |
|* 11 |           TABLE ACCESS FULL  | SALES     | 59158 |   751K|     1 |   16 |  Q1,00 | PCWP |           |
-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(COUNT(SYS_OP_CSR(SYS_OP_MSR(COUNT(*)),0))>100)
   9 - access("S"."CUST_ID"="C"."CUST_ID")
  11 - filter("S"."TIME_ID"<=TO_DATE(' 1999-10-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
"S"."TIME_ID">=TO_DATE(' 1999-07-01
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

ノート:

Cost (%CPU)列とTime列は、この例の計画表の出力では削除されています。

超並列処理(MPP)プラットフォームで実行されているOracle RAC環境で適切なスケーラビリティを得るには、パーティションをノード上に配置することが重要です。リモートI/Oを回避するには、一致する2つのパーティションが、同じノードに対してアフィニティを持っている必要があります。ボトルネックを回避し、システムで使用可能なすべてのCPUリソースを使用するために、パーティションの組がすべてのノードに分散される必要があります。

ノードの数よりパーティションの組の数が多い場合は、ノードで複数の組を管理できます。たとえば、ノード数が8のシステムでパーティションが16組ある場合は、各ノードが2組のパーティションに対応します。

関連項目:

データ・アフィニティの詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください

3.2.1.3 フル・パーティション・ワイズ結合: コンポジット-単一レベル

コンポジットから単一レベルへのフル・パーティション・ワイズ結合は、単一レベル-単一レベル方法の一種です。

このシナリオでは、1つの表(通常は大きい方の表)が2つのディメンションでコンポジット・パーティション化され、サブパーティション・キーとして結合列が使用されます。この例ではsales表が、履歴データを格納する表の一般的な例です。レンジ・パーティション化は、履歴情報を格納する表に対して、通常最初に行うパーティション化方法です。

たとえば、sales表を列time_idの範囲によって8個のパーティションにパーティション化するとします。また、2年分のデータがあり、各パーティションは四半期を表します。レンジ・パーティション化のかわりに、コンポジット・パーティション化を使用して、time_idでのパーティション化を維持しながらフル・パーティション・ワイズ結合を有効にすることができます。たとえば、sales表をtime_idの範囲でパーティション化し、各パーティションを16個のサブパーティションを使用してcust_idのハッシュでサブパーティション化します(サブパーティションの合計は128個)。customers表は、16パーティションでのハッシュ・パーティション化を使用できます。

ここで説明した方法を使用すると、フル・パーティション・ワイズ結合は、単一レベル-単一レベルのハッシュ-ハッシュ方法と同様に動作します。また、結合も、両方の表のハッシュ・パーティションの組の間で、16の小規模な結合に分割されます。違いは、sales表の各ハッシュ・パーティションが、各レンジ・パーティションから1つずつ、8つのサブパーティションの集合で構成されているということです。

図3-2は、sales表でハッシュ・パーティション化がどのように実現されるかを示します。各セルがサブパーティションを表します。全体で8個のレンジ・パーティションがあり、各行は1つのレンジ・パーティションに対応します。各レンジ・パーティションには16個のサブパーティションがあります。全体で16個のハッシュ・パーティションがあり、各列は1つのハッシュ・パーティションに対応します。各ハッシュ・パーティションには8個のサブパーティションがあります。ハッシュ・パーティションを定義できるのは、すべてのパーティションに同数のサブパーティション(ここでは16個)がある場合のみです。

ハッシュ・パーティションはコンポジット表では暗黙的に扱われます。ただし、データ・ディクショナリには記録されず、レンジ・パーティションやリスト・パーティションのようにDDLコマンドを使用して処理することはできません。

図3-2 コンポジット表のレンジ・パーティションおよびハッシュ・パーティション

図3-2の説明が続きます
「図3-2 コンポジット表のレンジ・パーティションおよびハッシュ・パーティション」の説明

次の例では、sales表のフル・パーティション・ワイズ結合の実行計画が示されます。この表は、time_idについてレンジ・パーティション化され、cust_idについてハッシュでサブパーティション化されています。

----------------------------------------------------------------------------------------------
| Id  | Operation                            | Name      | Pstart| Pstop |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |           |       |       |      |            |
|   1 |  PX COORDINATOR                      |           |       |       |      |            |
|   2 |   PX SEND QC (RANDOM)                | :TQ10001  |       |       | P->S | QC (RAND)  |
|*  3 |    FILTER                            |           |       |       | PCWC |            |
|   4 |     HASH GROUP BY                    |           |       |       | PCWP |            |
|   5 |      PX RECEIVE                      |           |       |       | PCWP |            |
|   6 |       PX SEND HASH                   | :TQ10000  |       |       | P->P | HASH       |
|   7 |        HASH GROUP BY                 |           |       |       | PCWP |            |
|   8 |         PX PARTITION HASH ALL        |           |     1 |    16 | PCWC |            |
|*  9 |          HASH JOIN                   |           |       |       | PCWP |            |
|  10 |           TABLE ACCESS FULL          | CUSTOMERS |     1 |    16 | PCWP |            |
|  11 |           PX PARTITION RANGE ITERATOR|           |     8 |     9 | PCWC |            |
|* 12 |            TABLE ACCESS FULL         | SALES     |   113 |   144 | PCWP |            |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(COUNT(SYS_OP_CSR(SYS_OP_MSR(COUNT(*)),0))>100)
   9 - access("S"."CUST_ID"="C"."CUST_ID")
  12 - filter("S"."TIME_ID"<=TO_DATE(' 1999-10-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
"S"."TIME_ID">=TO_DATE(' 1999-07-01
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

ノート:

Rows列、Cost (%CPU)列、Time列およびTQ列は、この例の計画表の出力では削除されています。

コンポジット-単一レベルのパーティション化が効率的なのは、あるディメンションではプルーニングを行い、別のディメンションではフル・パーティション・ワイズ結合を行えるためです。前述の問合せの例では、1999年の第3四半期に相当するサブパーティション(図3-2の3番目の行)のみをスキャンして、プルーニングが実現されます。Oracleによって、フル・パーティション・ワイズ結合が使用され、これらのサブパーティションがcustomer表と結合されます。

単一レベル-単一レベルのパーティション・ワイズ結合のすべての特性は、コンポジット-単一レベルのパーティション・ワイズ結合にも該当します。特に、この例では、2つの方法は次の2つの点で共通しています。

  • この場合のフル・パーティション・ワイズ結合の並列度は、16を超えることはありません。sales表に128のサブパーティションがあっても、ハッシュパーティションは16のみであるためです。

  • パーティションはサブパーティションの集合です。たとえば、図3-2では、sales表のハッシュ・パーティション9(楕円で囲まれた8つのサブパーティション)をcustomers表のハッシュ・パーティション9と同じノードに格納します。

3.2.1.4 フル・パーティション・ワイズ結合: コンポジット-コンポジット

より柔軟性を求める場合、コンポジットからコンポジットへのフル・パーティション・ワイズ結合を使用できます。

必要に応じて、customers表をコンポジット方法でパーティション化することもできます。たとえば、郵便番号の列についてこの表をレンジ・パーティション化して、郵便番号に基づくプルーニングを使用可能にできます。その後、同数(16)のパーティションを使用し、cust_idについてハッシュでサブパーティション化し、ハッシュ・ディメンションでパーティション・ワイズ結合を使用可能にします。

フル・パーティション・ワイズ結合は、パーティションとサブパーティションのすべての組合せ(パーティションとパーティション、パーティションとサブパーティション、サブパーティションとパーティション、サブパーティションとサブパーティション)で行うことができます。

3.2.2 パーシャル・パーティション・ワイズ結合

パーシャル・パーティション・ワイズ結合では、1つの表のみを結合キーでパーティション化する必要があります。

Oracle Databaseでは、パラレル時のみパーシャル・パーティション・ワイズ結合が実行できます。フル・パーティション・ワイズ結合と異なり、パーシャル・パーティション・ワイズ結合では、両方の表ではなく、一方の表のみを結合キーでパーティション化する必要があります。パーティション化された表は、参照表と呼ばれます。もう一方の表は、パーティション化してもしなくてもかまいません。パーシャル・パーティション・ワイズ結合は、フル・パーティション・ワイズ結合よりも一般的です。

パーシャル・パーティション・ワイズ結合を実行するために、データベースによって、参照表のパーティション化に基づいて、もう一方の表が動的に再パーティション化されます。もう一方の表が再パーティション化された後は、フル・パーティション・ワイズ結合と同様に実行されます。

パーシャル・パーティション・ワイズ結合が、非パーティション表の結合よりパフォーマンス上でメリットがあるのは、結合操作の間に参照表が移動しないことです。非パーティション表間のパラレル結合では、両方の入力表を結合キーについて再分散する必要があります。この再分散操作には、パラレル実行サーバー間での行の交換が伴います。これはCPU集中型の操作であり、Oracle RAC環境ではインターコネクト・トラフィックが増大する原因になります。結合キー(外部キーまたは主キー)で大規模な表をパーティション化すると、そのキーで表を結合するたびにこの再分散が発生することを防止できます。ただし、外部キーで表をパーティション化する場合(最も一般的な場合)は、多くの問合せに含まれる外部キーを選択する必要があります。

パーシャル・パーティション・ワイズ結合を説明するために、前のsales/customersの例を使用します。customersがパーティション化されていないか、cust_id以外の列でパーティション化されているとします。salesは多くの場合cust_idcustomersと結合されることが多く、この結合がアプリケーションのワークロードを占有します。このため、salescust_idでパーティション化して、customerssalesが結合されるたびに、パーシャル・パーティション・ワイズ結合が使用可能になるようにします。フル・パーティション・ワイズ結合と同じく、次に示す他の方法もあります。

3.2.2.1 パーシャル・パーティション・ワイズ結合: 単一レベル・パーティション化

単一レベル・パーシャル・パーティション・ワイズ結合は、パーシャル・パーティション・ワイズ結合を使用可能にする最も簡単な方法です。

たとえば、単一レベル・パーシャル・パーティション・ワイズ結合を使用可能にして、salescust_idでハッシュ・パーティション化できます。パーティションは、パーシャル・パーティション・ワイズ結合操作におけるパラレル化の最小グラニュルであるため、並列度の最大値はパーティションの数によって決定されます。

パーシャル・パーティション・ワイズ結合のパラレル実行を図3-3に示します。ここでは、並列度とsalesのパーティション数はどちらも16です。この実行では、2つのセットの問合せサーバーが使用されます。図3-3セット1customers表をパラレルでスキャンします。スキャン操作のパラレル化のグラニュルはブロックの範囲です。

セット1によって選択されたcustomers表の行(この場合はすべての行)は、cust_idをハッシュすることで、セット2の問合せサーバーに再分散されます。たとえば、sales表のパーティションP1の行と一致する可能性があるcustomers表の行はすべて、セット2の問合せサーバー1に送られます。セット2の問合せサーバーが受け取った行は、sales表にある対応するパーティションの行と結合されます。セット2の問合せサーバー1は、受け取ったcustomers表のすべての行とsales表のパーティションP1を結合します。

図3-3 パーシャル・パーティション・ワイズ結合

図3-3の説明が続きます
「図3-3 パーシャル・パーティション・ワイズ結合」の説明

次の例に、sales表とcustomers表のパーシャル・パーティション・ワイズ結合の実行計画を示します。

-----------------------------------------------------------------------------------------------
| Id  | Operation                             | Name      | Pstart| Pstop |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |           |       |       |      |            |
|   1 |  PX COORDINATOR                       |           |       |       |      |            |
|   2 |   PX SEND QC (RANDOM)                 | :TQ10002  |       |       | P->S | QC (RAND)  |
|*  3 |    FILTER                             |           |       |       | PCWC |            |
|   4 |     HASH GROUP BY                     |           |       |       | PCWP |            |
|   5 |      PX RECEIVE                       |           |       |       | PCWP |            |
|   6 |       PX SEND HASH                    | :TQ10001  |       |       | P->P | HASH       |
|   7 |        HASH GROUP BY                  |           |       |       | PCWP |            |
|*  8 |         HASH JOIN                     |           |       |       | PCWP |            |
|   9 |          PART JOIN FILTER CREATE      | :BF0000   |       |       | PCWP |            |
|  10 |           PX RECEIVE                  |           |       |       | PCWP |            |
|  11 |            PX SEND PARTITION (KEY)    | :TQ10000  |       |       | P->P | PART (KEY) |
|  12 |             PX BLOCK ITERATOR         |           |       |       | PCWC |            |
|  13 |              TABLE ACCESS FULL        | CUSTOMERS |       |       | PCWP |            |
|  14 |          PX PARTITION HASH JOIN-FILTER|           |:BF0000|:BF0000| PCWC |            |
|* 15 |           TABLE ACCESS FULL           | SALES     |:BF0000|:BF0000| PCWP |            |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(COUNT(SYS_OP_CSR(SYS_OP_MSR(COUNT(*)),0))>100)
   8 - access("S"."CUST_ID"="C"."CUST_ID")
  15 - filter("S"."TIME_ID"<=TO_DATE(' 1999-10-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
"S"."TIME_ID">=TO_DATE(' 1999-07-01
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

PX行ソースが存在するため、計画に表示されているように、この問合せはパラレルで実行されます。1つの表、SALES表がパーティション化されています。PX PARTITION HASH行ソースに、PX SEND PARTITIONによって結合を実行する別のワーカー・セットに分散されたパーティション化されていない表CUSTOMERSが含まれているため、このことを判別できます。

ノート:

Rows列、Cost (%CPU)列、Time列およびTQ列は、この例の計画表の出力では削除されています。

ノート:

この説明はハッシュ・パーティション化についてですが、レンジ、リストおよび時間隔のパーシャル・パーティション・ワイズ結合にも当てはまります。

フル・パーティション・ワイズ結合に関する考慮点は、次のようにパーシャル・パーティション・ワイズ結合にも適用されます。

  • 並列度は、パーティションの数と同じでなくてもかまいません。図3-3では、16の問合せサーバー2組で問合せが実行されています。ここでは、セット2の各問合せサーバーに1つのパーティションが割り当てられます。パーティションの数は常に並列度の倍数である必要があります。

  • MPPにおけるOracle RAC環境では、リモートI/Oを回避するために、sales表の各ハッシュ・パーティションが1つのノードのみに対してアフィニティを持つことが望ましいとされます。また、ボトルネックを回避し、システムで使用可能なすべてのCPUリソースを使用するために、パーティションをすべてのノードに分散させます。ノードの数よりパーティションの数が多い場合は、1つのノードで複数のパーティションを管理できます。

    関連項目:

    データ・アフィニティの詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください

3.2.2.2 パーシャル・パーティション・ワイズ結合: コンポジット

コンポジット・パーシャル・パーティション・ワイズ結合を使用できます。

フル・パーティション・ワイズ結合と同様に、sales表の最適なパーティション化方法は、time_id列に対してレンジ方法を使用することです。これは、sales表が、履歴データを格納する表の典型であるためです。このレンジ・パーティション化を維持して、パーシャル・パーティション・ワイズ結合を使用可能にするには、sales表をcust_id列でハッシュによってサブパーティション化し、各パーティションが16のサブパーティションに分かれるようにします。問合せによってcustomers表とsales表が結合され、time_idに関する選択述語がその問合せにある場合、プルーニングとパーシャル・パーティション・ワイズ結合の両方を使用できます。

sales表がコンポジット・パーティション化されているとき、パーシャル・パーティション・ワイズ結合のパラレル化のグラニュルは、サブパーティションではなくハッシュ・パーティションです。コンポジット表のハッシュ・パーティションの図は、図3-2を参照してください。ハッシュ・パーティションの数は並列度の倍数である必要があります。また、MPPシステムでは、各ハッシュ・パーティションが1つのノードに対してアフィニティを持つようにしてください。前の例では、1つのハッシュ・パーティションを構成する8個のサブパーティションが同じノードに対するアフィニティを持っています。

ノート:

この説明はレンジ-ハッシュに関してですが、他のすべての組合せのコンポジット・パーシャル・パーティション・ワイズ結合にも当てはまります。

次の例では、salescustomersの間の問合せの実行計画が示されます。sales表は、time_idについてレンジ・パーティション化され、cust_idについてハッシュでサブパーティション化されています。

---------------------------------------------------------------------------------------------
| Id  | Operation                           | Name      | Pstart| Pstop |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |           |       |       |      |            |
|   1 |  PX COORDINATOR                     |           |       |       |      |            |
|   2 |   PX SEND QC (RANDOM)               | :TQ10002  |       |       | P->S | QC (RAND)  |
|*  3 |    FILTER                           |           |       |       | PCWC |            |
|   4 |     HASH GROUP BY                   |           |       |       | PCWP |            |
|   5 |      PX RECEIVE                     |           |       |       | PCWP |            |
|   6 |       PX SEND HASH                  | :TQ10001  |       |       | P->P | HASH       |
|   7 |        HASH GROUP BY                |           |       |       | PCWP |            |
|*  8 |         HASH JOIN                   |           |       |       | PCWP |            |
|   9 |          PART JOIN FILTER CREATE    | :BF0000   |       |       | PCWP |            |
|  10 |           PX RECEIVE                |           |       |       | PCWP |            |
|  11 |            PX SEND PARTITION (KEY)  | :TQ10000  |       |       | P->P | PART (KEY) |
|  12 |             PX BLOCK ITERATOR       |           |       |       | PCWC |            |
|  13 |              TABLE ACCESS FULL      | CUSTOMERS |       |       | PCWP |            |
|  14 |          PX PARTITION RANGE ITERATOR|           |     8 |     9 | PCWC |            |
|  15 |           PX PARTITION HASH ALL     |           |     1 |    16 | PCWC |            |
|* 16 |            TABLE ACCESS FULL        | SALES     |   113 |   144 | PCWP |            |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(COUNT(SYS_OP_CSR(SYS_OP_MSR(COUNT(*)),0))>100)
   8 - access("S"."CUST_ID"="C"."CUST_ID")
  16 - filter("S"."TIME_ID"<=TO_DATE(' 1999-10-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND 
"S"."TIME_ID">=TO_DATE(' 1999-07-01
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

ノート:

Rows列、Cost (%CPU)列、Time列およびTQ列は、この例の計画表の出力では削除されています。