Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[ OracleTechnologyNight#102]SQL性能改善の武器としてのパラレル実行詳細

[ OracleTechnologyNight#102]SQL性能改善の武器としてのパラレル実行詳細

2026/08/27開催

■タイトル
SQL性能改善の武器としてのパラレル実行詳細

■アブストラクト
2026年05月21日に開催されたオフラインイベントOracle Developer Day 2026の講演内容「SQL性能改善の武器としてのパラレル実行:実行計画で見抜く“効く/効かない”パターン」に内容を追加してお届けします。
Oracle DatabaseのSQL性能改善における強力な武器であるパラレル実行を、実務目線で踏み込んで解説します。
イベントでは時間の制約もあり、データ・スキューやパラレル間データ通信にスポットを当てて解説しましたが、今回はスキャンの並列実行など基礎部分を主に追加する予定です。

Avatar for oracle4engineer

oracle4engineer PRO

August 27, 2026

Video

More Decks by oracle4engineer

Transcript

  1. SQLのパラレル実⾏とは • 単⼀のSQLの処理を複数プロセスで並列実⾏することで、⾼速に実⾏する機能 • Oracle Enterprise Editionの標準機能 • ⼤量データを扱うDWHまたはバッチ処理のSQLで有効 •

    アプリケーションからは透過的 • パラレルクエリの他にDML、DDLもあります。SQL以外もRMAN、Datapumpなどなどあります(※) (※)Oracle Database 19c 機能概要 4 Copyright © 2026, Oracle and/or its affiliates
  2. パラレルクエリの設定⽅法 SQLの内容を書き換えることなく、簡単な命令を付け⾜すだけでパラレル実⾏できる オブジェクト(表や索引)に対してパラレル属性を定義する CREATE TABLE <テーブル名> PARALLEL <DOP> セッションレベルで設定 ALTER

    SESSION FORCE PARALLEL QUERY PARALLEL <DOP> ヒント句をSQLに埋め込んで設定 SELECT /*+ PARALLEL(<表別名> <DOP>) */ ・・・ FROM <テーブル名> <表別名> ・・・; --テーブル指定を省略したらSELECT⽂の全てのテーブルが対象 SELECT /*+ PARALLEL(<DOP>) */ ・・・ FROM <テーブル名> <表別名> ・・・; 初期化パラメータで⾃動並列度を有効化 ALTER SYSTEM SET PARALLEL_DEGREE_POLICY=LIMITED|AUTO|ADAPTIVE; --デフォルトは MANUAL(⾃動並列度無効) ADWはデフォルトAUTO(コンシューマグループLOWはシリアル) パラレル設定の優先度は、ヒント句 > セッションレベル > ⾃動並列度 >オブジェクト指定 DOP指定を省略した場合、DOP= cpu_count * parallel_threads_per_cpu * RACインスタンス数 6 Copyright © 2026, Oracle and/or its affiliates
  3. 基礎値どりの例 ⼤きいサイズの表を⽤意する。例えば、ここでは、100GBで名前を100G_TABLEとします。 案件で使うサイズ、パラレルでスケールしたときに意味のあるサイズを定めてください (サイズが⼩さく、パラレル 8で2秒、16で1秒になったとしても誤差かどうかわかりにくい) テストテーブルの作成⽅法は、しばちょう先⽣の試して納得︕DBAの道 第3回参照 --時間測定のため設定 SET TIMING

    ON --今回検証ではキャッシュの性能影響はほぼないと⾔えるが条件をそろえるおまじない ALTER SYSTEM FLUSH BUFFER CACHE; ALTER SYSTEM FLUSH SHARED_POOL; ALTER SESSION FORCE PARALLEL QUERY PARALLEL [パラレル度] --このSQLの実⾏時間を測定。 SELECT COUNT(*) FROM 100G_TABLE ; 11 Copyright © 2026, Oracle and/or its affiliates このセットをパラレル度を変えながら 繰り返し実⾏して測定
  4. パラレル実⾏のスキャン⽅法 ダイレクト・パス・リードで実施(In-Memory PX,⼩さいテーブルの場合は除外) • • • • • • ディスクからバッファ・キャッシュを介さず直接PGAにバッファ読み込み

    HWM(High Water Mark)まで、マルチ・ブロック・リードによるスキャンを実施 スキャン⽅式は、全表スキャン(TABLE ACCESS FULL)および索引⾼速フルスキャン(INDEX FAST FULL SCAN) このため、パラレルクエリでの結合⽅式はハッシュ結合が選択されることが多い ⼤きめの表(Long Table)であればシリアル実⾏でもダイレクト・パス・リードはおこる Exadataのスマートスキャンの前提条件でもあるため、パラレル実⾏はExadataと親和性が⾼い 該当するオブジェクトのみ対象としたチェックポイント(ミニ・チェックポイント)が発⽣ enq:KO – fast object checkpoint 索引⾼速スキャンのダイレクト・パス・リード 全表スキャンのダイレクト・パス・リード バッファ・ キャッシュ PGA ⼀回のIOで複数ブロック読み込み (1回のIOサイズは、ほとんどのプ HWM ラットフォームで1MB。8Kブロック の場合、128個) ブロック 使⽤中ブロック 12 Copyright © 2026, Oracle and/or its affiliates セグメント・ヘッダ root L11 B1 L21 L22 B2 ツリー構造を意識せず、 割り当て済みブロックの集 合としてスキャン。 マルチ・ブロック・リードで実 施
  5. ハッシュ結合 orders表とorderitems表の結合 SELECT o.customer_name, l.unit_price * l.quantity FROM orders o,

    order_items l WHERE l.order_id = o.order_id; ①外部表からメモリ上に ハッシュテーブル作成 外部表(ビルド表) ORDER_ ID ORDER_STA TUS ITEM_ID ORDER_I D QUAN TITY UNIT_PR ICE 5001 1001 キーボード 2 4500 5002 1001 マウス 1 2500 PRODUCT_NAME CUSTOME R_NAME ORDER_D ATE 1001 佐藤商事 2026/7/1 SHIPPED 11500 5003 1002 モニター 1 32000 1002 鈴⽊物産 2026/7/2 PROCESSING 32000 5004 1003 USBケーブル 3 1200 1003 ⽥中⼯業 2026/7/3 SHIPPED 15600 1004 ⾼橋電機 2026/7/4 CANCELLED 0 5005 1003 ドッキングステーション 1 12000 1005 伊藤産業 2026/7/5 PROCESSING 28000 5006 1005 オフィスチェア 1 28000 5007 1007 SSD 2 9500 5008 1007 メモリー 2 6800 5009 1009 Webカメラ 1 8500 5010 1009 ヘッドセット 1 7200 ・・・ orders表 TOTAL_ AMOUNT 内部表(プローブ表) ②内部表を1度 だけ全表スキャン しながら結合 ・・・ orderitems表 13 Copyright © 2026, Oracle and/or its affiliates
  6. ハッシュ結合 Bloom Filterによる内部表(probe表)の結合前フィルタリング Bloom Filterとは、内部表(Build)側の結合キーから作るビット配列。 ⾮常に⼩さいサイズで、「絶対に⼀致しない」⾏、もしくは「⼀致する可能性がある」⾏を判別するフィルタを作成することができる。 この性質を使い、外部表(Probe)側の⾏をハッシュ結合前に事前フィルタリングが可能 厳密な⼀致条件については後続の結合処理で判定する Bloom Filiterのイメージ

    1 1 0 1 1 Bloom Filterありのハッシュ結合 内部表(Probe) 外部表(Build) 作 成 ハッシュ 表 結 合 BF B F 0 0 0 Bloom Filterは多段適⽤可能 作 成 ハッシュ 表1 BF1 外部表2(Build) 内部表の⾏が減らせそうな場合、 Bloom Filterが作成される 作 成 ハッシュ 表2 BF2 14 Copyright © 2026, Oracle and/or its affiliates 内部表(Probe) 外部表1(Build) ハッシュ 表1 ハッシュ 表2 結 合 結 合 B B F F 2 1
  7. ここまでのまとめ SQLのパラレル実⾏の基礎の内容をお伝えしました • SQLのパラレル実⾏はパラレル度をあげてリソースの続く限り性能をあげる • SQLの内容を書き換えることなく、簡単な命令を付け⾜すだけでパラレル実⾏できる • ジョブの例 • 26aiでのパラレルDMLのトランザクション制限の撤廃

    • パラレル実⾏の性能限界のあたりをつけるために⾃分のDBシステムではリソースのどこに限界があるか • 基礎値どりをして、どのくらいのサイズでどのくらいのパラレル度まで性能がでるか把握する • パラレル実⾏のスキャン⽅法はダイレクト・パス・リード • 全表スキャン、索引⾼速スキャンで実施。結合はハッシュ結合が選択されることが多い • ハッシュ結合の復習。都度アクセスでなく、1回全表スキャン形式なのでパラレル実⾏で選ばれることが多い。 • 後のページでパラレル実⾏で活躍するBloom Filterも紹介 15 Copyright © 2026, Oracle and/or its affiliates
  8. ⼀番シンプルなパラレル実⾏の実⾏計画 パラレル実⾏のイメージを掴む、まずは⼀番シンプルなパラレル実⾏の実⾏計画 SQL> SELECT /*+ FULL(t) PARALLEL(t 4) */ *

    FROM tab01 t; 実行計画 -------------------------------------------------------------------------------⾚⽮印はパラレル独⾃の項⽬ですが、 | Id | Operation | Name | TQ | IN-OUT | PQ Distrib | 今のようにスキャンだけのときは特に気に -------------------------------------------------------------------------------しなくとも⼤丈夫です | 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) |:TQ10000| Q1,00 | P->S | QC (RAND) | | 3 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 4 | TABLE ACCESS FULL | TAB01 | Q1,00 | PCWP | | -------------------------------------------------------------------------------- これがパラレルでスキャンするときの⽅法 ※パラレル実⾏の実⾏計画をみるときの推奨は リアルタイムSQL監視(アクティブレポート)でみることですが、 今回は、実⾏計画を解説する上でテキストが都合がいいため テキストでの実⾏計画で解説しています。 リアルタイムSQL監視でのパラレル実⾏の⾒⽅は以下をご参照ください ホワイトペーパー︓Oracle Databaseでのパラレル実⾏ 17 Copyright © 2026, Oracle and/or its affiliates
  9. パラレル実⾏のグラニュル ブロック・レンジ・グラニュルとパーティション・グラニュル 各PXは操作を1回に1グラニュルずつ実⾏。グラニュルには以下の2種類あります。 ブロック・レンジ・グラニュル PX BLOCK ITERATOR • PX PX

    • • • PX PX • ほとんどのパラレル操作 の基本ユニット ブロックをベースとして 区切った単位 オブジェクトのサイズと パラレル度によって決まる グラニュルの数はパラレル度 よりはるかに⼤きな数になる (均等に実⾏されるよう に) パーティション表でもこちらが 選択されることもある パーティション・グラニュル • パーティション1 PX パーティション2 PX パーティション3 パーティション4 パーティション5 ・・・ パーティション6 18 Copyright © 2026, Oracle and/or its affiliates PARTITION RANGE ALL PX PARTITION HASH ALL • • • 1パーティションにつき1グラ ニュル パーティション・ワイズ・ジョイ ン/パラレル索引レンジ・ス キャン/パーティション表の複 数パーティションの変更およ び作成操作で選択 使⽤可能な最⼤並列度 はパーティション数(それ以 上のパラレル度を割り当て ても遊ぶPXが出てくる) パラレル度より多くのパー ティション数(理想的には パラレル度の3倍)であるこ とがPXごとの処理の均等 化には望ましい
  10. OracleのSQLのパラレル実⾏の基本イメージ パラレル実⾏のイメージを掴む こちらはシリアル実⾏の実⾏計画です、これをパラレル度4でパラレル実⾏するとどうなると思いますか︖ SQL> SELECT c1, count(*) cnt FROM tab02

    2 GROUP BY c1 ORDER BY cnt; 実行計画 -------------------------------------Plan hash value: 774632932 -------------------------------------| Id | Operation | Name | -------------------------------------| 0 | SELECT STATEMENT | | | 1 | SORT ORDER BY | | | 2 | HASH GROUP BY | | | 3 | TABLE ACCESS FULL| TAB02 | 19 Copyright © 2026, Oracle and/or its affiliates
  11. OracleのSQLのパラレル実⾏の基本イメージ パラレル実⾏のイメージを掴む こちらはシリアル実⾏の実⾏計画です、これをパラレル度4でパラレル実⾏するとどうなると思いますか︖ 考え⽅1 実⾏計画のそれぞれのオペレーションをパラレル実⾏する(イントラ・オペレーション並列化) SQL> SELECT c1, count(*) cnt

    FROM tab02 2 GROUP BY c1 ORDER BY cnt; 20 それぞれのオペレーションをイントラ・オ ペレーションでパラレル実⾏する単位を PXサーバーセット(PXセット) といいます QC 実行計画 -------------------------------------Plan hash value: 774632932 PXセット2 OrderBy PX PX PX PX PXセット1 GroupBy PX PX PX PX -------------------------------------| Id | Operation | Name | -------------------------------------| 0 | SELECT STATEMENT | | | 1 | SORT ORDER BY | |◀パラレル度4 | 2 | HASH GROUP BY | |◀パラレル度4 | 3 | TABLE ACCESS FULL| TAB02 |◀パラレル度4 PXセット0 スキャン PX PX PX PX Copyright © 2026, Oracle and/or its affiliates 表 イントラ・オペレーション並列化
  12. OracleのSQLのパラレル実⾏の基本イメージ パラレル実⾏のイメージを掴む これはシリアル実⾏の実⾏計画です、これをパラレル度4でパラレル実⾏するとどうなると思いますか︖ 考え⽅1 実⾏計画のそれぞれのオペレーションをパラレル実⾏する(イントラ・オペレーション並列化) 考え⽅2 オペレーションをまたがってパラレル実⾏する(インター・オペレーション並列化) ▶両⽅発⽣します 前のPXセットの結果を⼊⼒として、次のPXセットが処理していくモ SQL>

    SELECT c1, count(*) cnt FROM tab02 2 GROUP BY c1 ORDER BY cnt; 実行計画 -------------------------------------Plan hash value: 774632932 デルをプロデューサ/コンシューマ・モデルと呼びます QCごとにPXセットは最 ⼤2セット同時実⾏しま す。つまり、最⼤でパラレ ル度×2のプロセス数での 実⾏となります -------------------------------------| Id | Operation | Name | -------------------------------------| 0 | SELECT STATEMENT | | | 1 | SORT ORDER BY | |◀パラレル度4 | 2 | HASH GROUP BY | |◀パラレル度4 | 3 | TABLE ACCESS FULL| TAB02 |◀パラレル度4 21 Copyright © 2026, Oracle and/or its affiliates ②GroupByしながら OrderBy ①スキャンしながら GroupBy ! " # $ % & ' ( $ ) * " 並 列 化 QC OrderBy PX PX PX PX GroupBy PX PX PX PX スキャン PX PX PX PX 表 イントラ・オペレーション並列化 ② ①
  13. パラレル実⾏の動作イメージを実⾏計画からつかむ 実⾏計画にあるパラレル実⾏独⾃のPX xxx、TQxxxx、TQ、IN-OUT、PQ Distribを利⽤して、PXセッ トから次のPXセットへデータを渡す流れのイメージをつかみます。 要素が多いですが、P→Pに注⽬するところから始めると楽です SELECT prod_id,SUM(amount_sold) FROM sales

    GROUP BY prod_id; ------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | | ------------------------------------------------------------------------22 Copyright © 2026, Oracle and/or its affiliates
  14. パラレル実⾏の動作イメージを実⾏計画からつかむ SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id; ------------------------------------------------------------------------| Id

    | Operation | Name | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | to | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | ① P→Pに注⽬します。P→P(Prallel | | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | Parallel)はPXセットが次のPXセットにデータを | 送るという意味で、各PXセットの処理の境⽬と ------------------------------------------------------------------------なります こちらはインター・オペレーション並列化の⽬印 として活⽤できます 23 Copyright © 2026, Oracle and/or its affiliates
  15. IN-OUT列 プロセス間通信 頭がPだとパラレル実⾏と覚えるとわかりやすい プロセス間通信する⽅式 P->P: Parallel to Parallel • PXが次のPXサーバー・セットに

    データを送る P->S: Parallel to Serial • PXがQCにデータを送る S->P: Serial to Parallel QCがPXにデータを送る • このステップはシリアル実⾏ • • 24 テーブル指定でパラレル実⾏して、 指定されてないテーブルの場合 Copyright © 2026, Oracle and/or its affiliates プロセス間通信しない⽅式 PCWP: Parallel Combined with Parent • 次のステップも同⼀のPXが⾏なう PCWC: Parallel Combined with Child • 前のステップと同⼀のPXが⾏なう こちらの2つが出ている間はPXセット間で通信が発⽣していない。 つまり同じPXセットで処理しつづけていることになります
  16. パラレル実⾏の動作イメージを実⾏計画からつかむ SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id; ------------------------------------------------------------------------| Id

    | Operation | Name | TQ |IN-OUT| PQ Distrib | ②TQの後ろ2桁の数字、もしくはTQ名の後ろ2 ------------------------------------------------------------------------②後ろの2桁の数字がPXセットの番号に該当、 桁がPXセットの番号です。Q1はQCの番号。① | 0 | SELECT STATEMENT | | | | | TQの後ろ2桁も同様。Q1はQCの番号 の⾚線を境に番号が変わっていることを確認。PX | 1 | PX COORDINATOR | | | | | セットの番号ごとに背景⾊を変えます | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | TQはPXセットの実⾏結果を次のPXセットに渡す | 3 | HASH GROUP BY | | Q1,01 | PCWP | | ための置き場のイメージ(※) | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH |(※)TQの補⾜ | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | |TQ︓テーブル・キューは抽象概念で実際に | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | |メモリ上にテーブルのような形で⽤意されるわ けではありません。 ------------------------------------------------------------------------TQ10000 PX TQ10001 PX QC SALES 25 PX PX PXセット00 PXセット01 Copyright © 2026, Oracle and/or its affiliates 実際には各プロセスがそれぞれキューを持っ ており、そこに置かれたデータをキュー・リファレ ンスという番号を使ってリンクしていています。 読み取ったデータは各プロセスのPGAから PGAに直接コピーされます
  17. パラレル実⾏の動作イメージを実⾏計画からつかむ SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id; ------------------------------------------------------------------------| Id

    | Operation | Name | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | ③ それぞれのPXセッ ③ それぞれのPXセッ | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | | ト内の実⾏計画から ト内の実⾏計画から ------------------------------------------------------------------------どんな処理をパラレル どんな処理をパラレル 実⾏しているかつかむ スキャン担当 TQ10000 GROUP BY担当 TQ10001 実⾏しているかつかむ PX PX QC SALES 26 PX PX PXセット00 PXセット01 Copyright © 2026, Oracle and/or its affiliates Tips︓ リアルタイムSQL監視では、PXセットご とに先頭の⼈マーク部分で⾊分けされ ています
  18. パラレル実⾏の動作イメージを実⾏計画からつかむ SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id; ------------------------------------------------------------------------| Id

    | Operation | Name | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | ④PX XXX関連のオ | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | | ペレーションの役割に ------------------------------------------------------------------------ついて把握する スキャン担当 TQ10000 GROUP BY担当 PX PX SALES PX BLOCK ITERATOR PX PX SEND HASH PXセット00 27 Copyright © 2026, Oracle and/or its affiliates TQ10001 PX RECEIVE PX SEND QC (RANDOM) PX PXセット01 QC
  19. PX SEND xxxまたはPQ Distrib 列 P->Pでの分散⽅式のみ抜粋 HASH(基本はこれを使⽤する) • ⼤量のデータを分割するのに最適。ハッシュ分散し、同じキーを同じPXへ送る •

    結合やGroup Byでの基本的な⽅式 • 重複データが多いときに、データの偏り(データ・スキュー)が発⽣ BROADCAST(結合の⽚⽅が⼩さい) • 結合で⽚⽅が⼩さい場合利⽤される⽅式 • ⼩さい⽅のデータセットをすべてのPXに配布 RANGE(ソートなど) • ソート・キーで分散、PXへの配分をキー順を保ったレンジで分ける ROUND-ROBIN • ⾏を順番にPXに配る⽅式 • PXへのデータの均等配布⽬的で使⽤ PARTITION • パーティション分割(⽚⽅がパーティション表のときのパーシャル・パーティション・ワイズ結合) 28 Copyright © 2026, Oracle and/or its affiliates
  20. ここまでのまとめ SQLのパラレル実⾏の⾒⽅の勘所をお伝えしました • 基本的なパラレル実⾏の実⾏計画 • スキャンオペレーション︓ブロック・レンジ・グラニュル(PX BLOCK ITERATOR)とパーティショ ン・グラニュル(PARTITION RANGE

    ALL) • インターオペレーションパラレル実⾏を実施する実⾏計画 • P→Pに注⽬して、前後で違うPXセットが実⾏されているかを意識するとイメージしやすい • IN-OUT列 • PX SEND xxxまたはPQ Distrib 列 29 Copyright © 2026, Oracle and/or its affiliates
  21. データ・スキュー(データの偏り) データ・スキューとPX間処理量の偏りが起こす性能問題 理想的なパラレル実⾏ データ・スキューが発⽣している場合 各PXに対して処理するデータ量が同じ。 各PXの処理が同時に終わり、PXの待ちが発⽣しない 各PXで処理するデータ量が異なる 偏りが⼤きいPXの終了を、他のPXが待つ形になる PX1 PX2

    PX3 PX4 PX1 PX2 PX3 PX4 PX SEND HASHでは、結合キーや集約キーのキーのハッシュ 値で各⾏の送り先PXが決まります。キー値に偏りがあると、同じ キーの⾏は同じPXに集まるため、⼀部のPXだけが⼤量の⾏を 処理し、そこがボトルネックになります。 31 Copyright © 2026, Oracle and/or its affiliates
  22. 結合(HASH JOIN)でのPX SEND HASHのスキュー発⽣ 以下のSQLの実⾏計画を例に具体的なケースをみていきます データ・スキューの問題をみるため、特定顧客の注⽂が多いようなケースを想定します SALES表には特定顧客ID(例えばcust_id=1)の注⽂データが多数を占めている状況をイメージをしてください SELECT c.cust_email FROM

    sales s, customers c WHERE s.cust_id = c.cust_id AND s.amount_sold >= 1000 -------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | -------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10002 | Q1,02 | P->S | QC (RAND) | |* 3 | HASH JOIN | | Q1,02 | PCWP | | | 4 | PX RECEIVE | | Q1,02 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 7 | TABLE ACCESS FULL| CUSTOMERS | Q1,00 | PCWP | | | 8 | PX RECEIVE | | Q1,02 | PCWP | | | 9 | PX SEND HASH | :TQ10001 | Q1,01 | P->P | HASH | | 10 | PX BLOCK ITERATOR | | Q1,01 | PCWC | | |* 11 | TABLE ACCESS FULL| SALES | Q1,01 | PCWP | | -------------------------------------------------------------------------32 Copyright © 2026, Oracle and/or its affiliates
  23. 結合(HASH JOIN)でのPX SEND HASHのスキュー発⽣ スキャン担当 TQ10000 ハッシュジョイン担当 スキューにより上のPXのハッ シュ・ジョインの⽅が重い PX

    CUSTOMERS PX BLOCK ITERATOR PX PX SEND HASH PX RECEIVE ビルド PX PXセット00 スキャン担当 PX BLOCK ITERATOR PX TQ10001 プローブ PX SEND HASH PXセット01 33 Copyright © 2026, Oracle and/or its affiliates QC PX PX SALES TQ10002 スキュー発⽣ PX RECEIVE PXセット02
  24. V$PQ_TQSTATによるスキューの観測⽅法 各PXセットのProducerとComsumerのPX毎の⾏数がわかるためスキューの具合がわかります select tq_id,server_type,num_rows,process from v$pq_tqstat order by tq_id,server_type desc,process;

    TQ_ID SERVER_TYP NUM_ROWS PROCES ---------- ---------- ---------- -----0 Producer 0 P002 PX BLOCK ITERATOR 0 Producer 5 P003 外部表 0 Consumer 2 P000 CUSTOMERS側 PX RECEIVE= PX SEND HASH 0 Consumer 3 P001 内部表 SALES側 PX BLOCK ITERATOR PX RECEIVE= PX SEND HASH スキュー発⽣ 34 Copyright © 2026, Oracle and/or its affiliates 1 Producer 1 Producer 1 Consumer 1 Consumer 54353 P002 45647 P003 2 P000 99998 P001 2 Producer 2 Producer 2 Consumer 1 P000 1 P001 2 QC Tips︓ リアルタイムSQL監視では、各PXセット内でPX毎の DB Time/IO Count/Buffer Getsを確認するこ とで、スキューの発⽣を観測することができます
  25. 解決策︓BROADCASTによるデータ・スキュー解決 ⼤きな表と⼩さな表の結合のときにオプティマイザが判断して実⾏ ⼩さい表を、⼤きい表側をスキャンした各PXに配布(BROADCAST)し、その場で結合 • スキューを回避した形でハッシュジョインの並列化が可能 • ⼤きい表側のSEND HASHを防ぐことで、スキューの発⽣を防ぐだけでなく、PX間データ送信も防ぐ SELECT cu.cust_email

    FROM customers cu, countries co WHERE cu.country_id = co.country_id AND co.country_region = 'Asia' -------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | -------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | |* 3 | HASH JOIN | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND BROADCAST | :TQ10000 | Q1,00 | P->P | BROADCAST | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | |* 7 | TABLE ACCESS FULL| COUNTRIES | Q1,00 | PCWP | | | 8 | PX BLOCK ITERATOR | | Q1,01 | PCWC | | | 9 | TABLE ACCESS FULL | CUSTOMERS | Q1,01 | PCWP | | -------------------------------------------------------------------------35 Copyright © 2026, Oracle and/or its affiliates
  26. 解決策︓BROADCASTによる解決 スキャン担当 TQ10000 PX COUNTRIES PX BLOCK ITERATOR PX PX

    SEND BROADCAST PXセット00 スキャン&ハッシュジョイン担当 PX RECEIVE PX CUSTOMERS PX SEND QC(RANDOM) PX BLOCK ITERATOR PX PXセット01 36 Copyright © 2026, Oracle and/or its affiliates TQ10001 QC Tips︓ 統計情報が不正確で、BROADCASTした データセットが、実は⼤きかった場合、PX間 通信がボトルネックになります。 このトピックは後ででてきます 外部表をスキャンしたPXセットがSEND HASHせず、そのまま ハッシュジョインも実⾏することでデータスキューを回避している上 に、⼤きい⽅の表のデータ再分散も回避
  27. データ・スキューへのSQLでの対策︓ホット・キー分離 ホットキー側はBROADCAST、⾮ホット・キー側はPX SEND HASH ホット・キーとはデータが偏って多くの⾏をしめているキーのこと。 サンプルSQL(ホット・キー分離前) • ホット・キーはcustomer_id=1,2(これは割り出せていることが前提) • 主要取引先がほぼ決まっているような想定

    SELECT FROM JOIN WHERE AND GROUP c.customer_segment, SUM(s.amount) AS amount_sum sales_fact s dim_customer c ON c.customer_id = s.customer_id s.sales_date >= DATE '2026-05-01' s.sales_date < DATE '2026-06-01' BY c.customer_segment; SQL書き換え⽅針︓ • 元のSQLを、ホット・キー側と⾮ホット・キー側にわけてUNIONする • ホットキー側はBROADCAST、⾮ホット・キー側はPX SEND HASHを期待 38 Copyright © 2026, Oracle and/or its affiliates
  28. データ・スキューへのSQLでの対策の例 ホット・キー分離 /* customer_id=1,2がホット・キー */ WITH hot_keys AS ( SELECT

    1 AS customer_id FROM dual UNION ALL SELECT 2 AS customer_id FROM dual ) SELECT customer_segment, SUM(amount_sum) AS amount_sum FROM ( /* ホットキー⽤ブランチ */ SELECT c.customer_segment, SUM(s.amount) AS amount_sum FROM sales_fact s JOIN dim_customer c ON c.customer_id = s.customer_id WHERE s.sales_date >= DATE '2026-05-01' AND s.sales_date < DATE '2026-06-01' AND EXISTS ( SELECT 1 FROM hot_keys hk WHERE hk.customer_id = s.customer_id ) GROUP BY c.customer_segment ↗につづく 39 Copyright © 2026, Oracle and/or its affiliates UNION ALL /* ⾮ホットキー⽤ブランチ*/ SELECT c.customer_segment, SUM(s.amount) AS amount_sum FROM sales_fact s JOIN dim_customer c ON c.customer_id = s.customer_id WHERE s.sales_date >= DATE '2026-05-01' AND s.sales_date < DATE '2026-06-01' AND NOT EXISTS ( SELECT 1 FROM hot_keys hk WHERE hk.customer_id = s.customer_id ) GROUP BY c.customer_segment ) GROUP BY customer_segment;
  29. データ・スキューへのSQLでの対策の例 ホット・キー分離 /* customer_id=1,2がホット・キー */ WITH hot_keys AS ( SELECT

    1 AS customer_id FROM dual UNION ALL SELECT 2 AS customer_id FROM dual ) SELECT customer_segment, SUM(amount_sum) AS amount_sum FROM ( /* ホットキー⽤ブランチ */ ホット・キー側はBROADCAST SELECT HASH c.customer_segment, JOIN PX SUM(s.amount) RECEIVE AS amount_sum PX SEND BROADCAST -- DIM_CUSTOMER側 FROM sales_fact s TABLE ACCESSc FULL DIM_CUSTOMER JOIN dim_customer PX ON BLOCK ITERATOR = s.customer_id -- SALES_FACT側 c.customer_id ACCESS FULL SALES_FACT WHERE TABLE s.sales_date >= DATE '2026-05-01' AND s.sales_date < DATE '2026-06-01' AND EXISTS ( SELECT 1 FROM hot_keys hk WHERE hk.customer_id = s.customer_id ) GROUP BY c.customer_segment ↗につづく 40 Copyright © 2026, Oracle and/or its affiliates UNION ALL /* ⾮ホットキー⽤ブランチ*/ SELECT c.customer_segment, SUM(s.amount) AS amount_sum FROM sales_fact s JOIN dim_customer c ON c.customer_id = s.customer_id ⾮ホット・キー側はPX SEND>= HASH WHERE s.sales_date DATE '2026-05-01' HASH JOIN AND s.sales_date < DATE '2026-06-01' PX RECEIVE -- DIM_CUSTOMER側 AND NOT EXISTS ( PX SENDSELECT HASH 1 PX RECEIVEFROM -- SALES_FACT側 hot_keys hk PX SENDWHERE HASH hk.customer_id = s.customer_id ) GROUP BY c.customer_segment ) GROUP BY customer_segment; Tips︓ 実は、SQLはそのままで、これと似た動作をする機能が12cからあ ります。PX SEND HYBRID HASH(SKEW)です(後述)
  30. ここまでのまとめ SQLのパラレル実⾏で発⽣するデータ・スキューの課題に対するオラクルの解決策についてお伝えしました • データ・スキューの課題 • スキュー(キー値の偏り)が発⽣しているキーを担当したPXの処理遅延で他のPXが待機する • ハッシュ・ジョインのパラレル実⾏、BROADCASTよる解決 • ⽚⽅の表が⼩さいとき内部表をBROADCASTすることで、外部表のSEND

    HASHを回避することで データスキューの問題を回避 • ⼩さい内部表を、外部表側でのPXセットが直で読んで使⽤するSmall Table Replicate(12c)という 機能拡張もあります • SQL書き換えによるホット・キー分割の紹介。 SQLで、ホット・キーと⾮ホット・キー検索部分を別々に書 いて、UNIONする。こうすることで、ホット・キー側はBROADCAST、⾮ホット・キー側はPX SEND HASHを実現できる。これをSQL書き換えでなく、Oracle機能で実現するものは、後のページででてきま す 41 Copyright © 2026, Oracle and/or its affiliates
  31. パラレル間データ通信 PXセット間の通信で問題が発⽣するケース PXセット間の通信で問題が発⽣するケースを 扱います ここ ここ 問題が発⽣する代表例︓ ハッシュ結合で、SEND HASHすべき⼤きめ の表をBROADCASTしてしまった

    また、PXセット間の通信を抑えるために使える オラクルの機能も紹介します • GROUP BY PUSH DOWN • Bloom Filterによるハッシュ結合のPX間 メッセージサイズの削減 • パーティション・ワイズ結合 43 Copyright © 2026, Oracle and/or its affiliates
  32. 適応型パラレル分散⽅法︓PX SEND HYBRID HASH(12c以降) ⾒積もりミスによる⼤きいデータのBROADCASTを防ぐ 適応型パラレル分散⽅法︓ オプティマイザが統計情報だけでは、正確に⾒積もれないと判断した場合、実⾏計画作成時点では 分散⽅法を決定せず、実⾏時の⾏数を考慮して、分散⽅法を決定する機能 ハッシュジョインの外部表側の ⾏数が多ければ

    HASH ⾏数が少なければ BROADCAST 判断の閾値は、外部表側の実際の⾏数がパラレル度の2倍 これによって、実際に⾏数が多い場合に、誤ってBROADCASTされてしまうことを抑制できます 適応計画(Adaptive Plans)の機能のひとつ。デフォルト有効(19c,26ai) 44 Copyright © 2026, Oracle and/or its affiliates
  33. 津島博⼠のパフォーマンス講座 第39回 適応型パラレル分散⽅法︓PX SEND HYBRID HASH 実⾏計画の分散⽅法の確認 パラレル2 閾値 4

    パラレル4 閾値 8 SQL> SELECT COUNT(*) FROM ( SELECT /*+ pq_distribute(t1,hash,hash) */ * FROM t3,t1 WHERE t3.col1 = t1.col1); ----------------------------------------------------------------------------------------------- ---------| Id | Operation | Name | E-Rows | TQ |IN-OUT| PQ Distrib | A-Rows | | A-Rows | 外部表側の件数は5件 ----------------------------------------------------------------------------------------------- ---------| 0 | SELECT STATEMENT | | | | | | 1 | | 1 | 外部表側の件数が | 1 | SORT AGGREGATE | | 1 | | | | 1 | | 1 | 閾値より上︓HASH | 2 | PX COORDINATOR | | | | | | 2 | | 4 | 閾値より下︓BROADCAST | 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | Q1,02 | P->S | QC (RAND) | 0 | | 0 | | 4 | SORT AGGREGATE | | 1 | Q1,02 | PCWP | | 2 | | 4 | (閾値はパラレル度の2倍) |* 5 | HASH JOIN | | 50000 | Q1,02 | PCWP | | 100K| | 100K| | 6 | PX RECEIVE | | 5 | Q1,02 | PCWP | | 5 |HASH | 20 |BROADCAST | 7 | PX SEND HYBRID HASH | :TQ10000 | 5 | Q1,00 | P->P | HYBRID HASH| 0 | | 0 | | 8 | STATISTICS COLLECTOR | | | Q1,00 | PCWC | | 5 | | 5 | 5件 ×4 パラレル = 20 件 | 9 | PX BLOCK ITERATOR | | 5 | Q1,00 | PCWC | | 5 | | 5 | Tips︓ |* 10 | TABLE ACCESS FULL | T3 | 5 | Q1,00 | PCWP | | 5 | | 5 | A-RowsのBROADCASTの件数に注意 | 11 | PX RECEIVE | | 100K| Q1,02 | PCWP | | 100K| | 100K| | 12 | PX SEND HYBRID HASH | :TQ10001 | 100K| Q1,01 | P->P | HYBRID HASH| 0 | | 0 | 各PXにBROADCASTして膨らんだ件数が | 13 | PX BLOCK ITERATOR | | 100K| Q1,01 | PCWC | | 100K| | 100K| 出⼒される |* 14 | TABLE ACCESS FULL | T1 | 100K| Q1,01 | PCWP | | 100K| | 100K| 45 Copyright © 2026, Oracle and/or its affiliates Tips︓ リアルタイムSQL監視では、Other列の双眼 鏡アイコンからどの分散⽅法が選択されたか 確認できます。 Distribution method: 5︓ROUND-ROBIN 6︓BROADCAST 16︓HASH
  34. 津島博⼠のパフォーマンス講座 第39回 適応型パラレル分散⽅法︓PX SEND HYBRID HASH 外部表側がBROADCASTになった場合は、内部表側はROUND-ROBIN 外部表側 スキャン担当 TQ10000

    ハッシュジョイン担当 PXPX SEND T3 PX BLOCK ITERATOR HYBRID HASH (BROADCAST) PX PXセット00 内部表側 スキャン担当 TQ10001 PXPX SEND T1 PX BLOCK ITERATOR HYBRID HASH (ROUNDPXROBIN) PXセット01 46 Copyright © 2026, Oracle and/or its affiliates PX RECEIVE ビルド TQ10002 PX QC PX 参考︓通常のBROADCASTのハッシュ・ジョイン プローブ PXセット02 PX RECEIVE HYBRID HASHで外部表側がBROADCASTになった場合、内部表側 ではROUND-ROBINによって均等分散配布を⾏います。 通常のBROADCASTでは、内部表側をスキャンしたPXセットがそのまま ハッシュ・ジョインし、PX SEND処理を回避していましたが、 HYBRID HASHではそうはなりません。 これはHYBRID HASHでは、実⾏計画を⽴てた時点で、内部表のスキャ ンとハッシュジョインのPXセットは別と指定された上で、後から均等配布する ための制限と考えられます
  35. 津島博⼠のパフォーマンス講座 第39回 PX SEND HYBRID HASH(SKEW) SQL変更なしで重複値の多いホット・キーにはBROADCAST、⾮ホット・キーはSEND HASHを実施 SQLのホット・キー分割をせずに、ホット・キー分割を実現 •

    ホット・キー側はBROADCAST • ⾮ホット・キー側はHASH 結合列にヒストグラムが存在するか、PQ_SKEWヒントを使⽤していた場合に使⽤可能 47 Copyright © 2026, Oracle and/or its affiliates
  36. 津島博⼠のパフォーマンス講座 第39回 PX SEND HYBRID HASH(SKEW) 実⾏計画 SQL> ALTER SESSION

    FORCE PARALLEL QUERY PARALLEL 2; SQL> SELECT COUNT(*) FROM (SELECT /*+ pq_distribute(t1,hash,hash) pq_skew(t1) */ * FROM t3,t1 WHERE t3.col1 = t1.col1); --------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Starts | E-Rows | | TQ |IN-OUT| PQ Distrib | A-Rows | --------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | | | | | | 1 | | 1 | SORT AGGREGATE | | 1 | 1 | | | | | 1 | | 2 | PX COORDINATOR | | 1 | | | | | | 2 | | 3 | PX SEND QC (RANDOM) | :TQ10002 | 0 | 1 | | Q1,02 | P->S | QC (RAND) | 0 | | 4 | SORT AGGREGATE | | 2 | 1 | | Q1,02 | PCWP | | 2 | ホット・キーの100は2パラレルに |* 5 | HASH JOIN | | 2 | 50000 | | Q1,02 | PCWP | | 100K| BROADCASTするので2 | 6 | PX RECEIVE | | 2 | 5 | | Q1,02 | PCWP | | 6 | | 7 | PX SEND HYBRID HASH | :TQ10000 | 0 | 5 | | Q1,00 | P->P | HYBRID HASH| 0 | ⾮ホット・キーは残り4つと | 8 | STATISTICS COLLECTOR | | 2 | | | Q1,00 | PCWC | | 5 | 合わせて6 | 9 | PX BLOCK ITERATOR | | 2 | 5 | | Q1,00 | PCWC | | 5 | |* 10 | TABLE ACCESS FULL | T3 | 1 | 5 | | Q1,00 | PCWP | | 5 | T1のSCANと別のPXセットで結合 | 11 | PX RECEIVE | | 2 | 100K| | Q1,02 | PCWP | | 100K| | 12 | PX SEND HYBRID HASH (SKEW)| :TQ10001 | 0 | 100K| | Q1,01 | P->P | HYBRID HASH| 0 | するため、内部表側を均等配布す | 13 | PX BLOCK ITERATOR | | 2 | 100K| | Q1,01 | PCWC | | 100K| るのための、ROUND-ROBINは発 |* 14 | TABLE ACCESS FULL | T1 | 26 | 100K| | Q1,01 | PCWP | | 100K| T3︓全5⾏ (内部表側) COL1 COUNT(*) ---------- ---------1 1 2 1 3 1 4 1 1 ホット・キー → 100 48 Copyright © 2026, Oracle and/or its affiliates T1︓全100,000⾏ (外部表側) COL1 COUNT(*) ---------- ---------1 1 2 1 3 1 4 1 99996 ホット・キー → 100 ⽣
  37. 津島博⼠のパフォーマンス講座 第39回 PX SEND HYBRID HASH(SKEW) v$pq_tqstatから確認 SQL> select tq_id,server_type,num_rows,process

    from v$pq_tqstat order by tq_id,server_type desc,process; 外部表T3側 内部表T1側 49 TQ_ID SERVER_TYPE NUM_ROWS PROCESS ---------- -------------------- ---------- ---------6 P002 <-- 100を2個にして6⾏に PX BLOCK ITERATOR 0 Producer 0 Producer 0 P003 PX RECEIVE= 0 Consumer 3 P000 <-- どちらにも100をいれる PX SEND HYBRID 0 Consumer 3 P001 <-- どちらにも100をいれる HASH 1 Producer 49903 P002 PX BLOCK ITERATOR 1 Producer 50097 P003 1 Consumer 50001 P000 PX RECEIVE= 1 Consumer 49999 P001 PX SEND HYBRID HASH (SKEW) 2 Producer 1 P000 スキューの回避を確認 2 Producer 1 P001 2 Consumer 2 QC Copyright © 2026, Oracle and/or its affiliates
  38. GROUP BY PUSH DOWN GROUP BY PUSH DOWNの実⾏計画の⽐較 GROUP BY

    PUSH DOWNなしの場合 SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id ------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 7 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | | ------------------------------------------------------------------------- PX RECEIVE ここのPX SEND HASHするデータ量を減らせないか 50 Copyright © 2026, Oracle and/or its affiliates GROUP BY PUSH DOWNありの場合 SELECT prod_id,SUM(amount_sold) FROM sales GROUP BY prod_id -------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | -------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | | 3 | HASH GROUP BY | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH | | 6 | HASH GROUP BY | | Q1,00 | PCWP | | | 7 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 8 | TABLE ACCESS FULL| SALES | Q1,00 | PCWP | | -------------------------------------------------------------------------- PX RECEIVE このPX SEND HASHの前に部分集計を実施し て、PX間通信に必要なデータ量を削減
  39. GROUP BY PUSH DOWN(GPD) GROUP BYを早い段階で部分集計し、PXセット間に流すデータ量を削減する仕組み • 部分集計と最終集計の2段階でGROUP BYが発⽣するコストと、PXセット間のデータ量が削減されるコストを オプテイマイザが⽐較して⾃動決定

    • ユニーク度が⾼くGROUP BYの結果、結果件数があまり減らない集計処理には、GPDは不向き これもオプティマイザが判断 • RACのインターノード・パラレル実⾏の場合、通信量削減はさらに効果的 • 1PXあたりに求められる最⼤PGA量を低くする効果もあり • DISTINCTではGPDが発⽣しないので、GROUP BYに書き換えることで⾼速化することがある 51 Copyright © 2026, Oracle and/or its affiliates
  40. Oracle Database Technology Night #48 津島博⼠のパフォーマンス講座 - SQLチューニングは実⾏計画から p66 Bloom

    Filterによるハッシュ結合のPX間メッセージサイズの削減 52 Copyright © 2026, Oracle and/or its affiliates
  41. Oracle Database Technology Night #42 Oracle Real Application Clusters フル・パーティション・ワイズ結合

    パーティション定義が同じ表をパーティション・キー同⼠で結合 SELECT * FROM t1 INNER JOIN t2 ON t1.partkey = t2. partkey パーティション・キー パーティション・キー パーティション1 パーティション1 パーティション2 パーティション2 結合キーがパーティション・キー である場合、値が存在する パーティションが特定できる パーティション3 パーティション3 パーティション4 パーティション4 表1 53 パーティション・キーの 定義が同じ表 Copyright © 2026, Oracle and/or its affiliates 表2
  42. Oracle Database Technology Night #42 Oracle Real Application Clusters パーティションワイズ結合

    パーティション定義が同じ表をパーティション・キー同⼠で結合 SELECT * FROM t1 INNER JOIN t2 ON t1.partkey = t2. partkey パーティション・キー パーティション1 パーティション2 PX パーティション2 パーティション3 PX パーティション3 パーティション4 PX パーティション4 表1 54 パーティション・キー パーティションごとの結合を データ交換なしに並列実⾏ 可能 PX Copyright © 2026, Oracle and/or its affiliates パーティション1 表2
  43. フル・パーティション・ワイズ結合 最初からパラレル結合可能な形で分割されているため、再分配するPX間送信が必要ない 2個の表が両⽅とも結合キーでパーティション化されている場合 SELECT s.prod_id, c.unit_price FROM sales s, costs

    c WHERE s.prod_id = c.prod_id AND s.time_id = c.time_id AND s.promo_id = c.promo_id AND s.channel_id = c.channel_id AND s.amount_sold >= 1000 AND c.unit_price >= 1000 -------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | -------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10000 | Q1,00 | P->S | QC (RAND) | | 3 | PX PARTITION RANGE ALL| | Q1,00 | PCWC | | |* 4 | HASH JOIN | | Q1,00 | PCWP | | |* 5 | TABLE ACCESS FULL | COSTS | Q1,00 | PCWP | | |* 6 | TABLE ACCESS FULL | SALES | Q1,00 | PCWP | | --------------------------------------------------------------------------PXセットがひとつだけ、つまり PXセット間の通信が発⽣していない 55 Copyright © 2026, Oracle and/or its affiliates
  44. Oracle Database Technology Night #42 Oracle Real Application Clusters パーティションワイズ結合

    フル・パーティション・ワイズ結合になるパーティション設計ができるとは限らない パーティション・キー フル・パーティション・ワイズ結合にならない 表3 56 Copyright © 2026, Oracle and/or its affiliates パーティション・キー フル・パーティション・ワイズ結合 表1 表2 Oracle Database Technology Night #42 Oracle Real Application Clusters
  45. Oracle Database Technology Night #42 Oracle Real Application Clusters パーシャル・パーティション・ワイズ結合

    パーティション定義が異なる表の結合 Table Queueを使ってPXプロ セス間のデータ交換が可能 SELECT * FROM t1 INNER JOIN t2 ON t1.key = t2. partkey パーティション・キー 表3 57 パーティション・キー PX パーティションごとの結合を データ交換なしに並列実⾏ 可能 PX PX PX パーティション2 PX PX パーティション3 PX PX パーティション4 Table Queueで再配分してパーティショニング Copyright © 2026, Oracle and/or its affiliates パーティション1 表2
  46. パーシャル・パーティション・ワイズ結合 実⾏計画 SELECT s.prod_id, t.day_name FROM sales s, times t

    WHERE s.time_id = t.time_id AND s.amount_sold >= 1000 ----------------------------------------------------------------------------| Id | Operation | Name | TQ |IN-OUT| PQ Distrib | ----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | | | | | 1 | PX COORDINATOR | | | | | | 2 | PX SEND QC (RANDOM) | :TQ10001 | Q1,01 | P->S | QC (RAND) | |* 3 | HASH JOIN | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | Q1,01 | PCWP | | | 5 | PX SEND PARTITION (KEY)| :TQ10000 | Q1,00 | P->P | PART (KEY) | | 6 | PX BLOCK ITERATOR | | Q1,00 | PCWC | | | 7 | TABLE ACCESS FULL | TIMES | Q1,00 | PCWP | | | 8 | PX PARTITION RANGE ALL | | Q1,01 | PCWC | | |* 9 | TABLE ACCESS FULL | SALES | Q1,01 | PCWP | | ----------------------------------------------------------------------------SALESの⽅はパーティション・グラニュルでスキャン 結合も同じPXセットで実施しているので、⼤きい⽅のテーブル であるSALESの再分配が防がれている 58 Copyright © 2026, Oracle and/or its affiliates TIMESの⽅はSEND PARTITION(KEY)でパー ティション・キーに沿って再分配 している
  47. ここまでのまとめ SQLのパラレル実⾏で発⽣するパラレル間データ通信の課題に対するオラクルの解決策についてお伝えしました • パラレル間データ通信の課題 • 代表的なのは、ハッシュ結合で、あやまって⼤きいサイズの表をBROADCASTしてしまった場合 • Oracle機能での解決策として、実際の⾏数をみて、BROADCASTかSEND HASHか切り替え るPX

    SEND HYBRID HASH(12c) • PX SEND HYBRID HASHの亜種で、スキュー対策に役⽴つPX SEND HYBRID HASH (SKEW)もあります。こちらはホットキー分離をSQL書き換えでなくOracleの機能で実現できる 機能 • GROUP BY PUSH DOWN • PX間通信する前に事前にGROUP BYを追加することで、通信データサイズを⼩さくする • Bloom Filterによるハッシュ結合のPX間メッセージサイズの削減 • PX間通信する前にBloom Filterでデータをフィルタリングし、削減してから通信 • パーティション・ワイズ結合 • すでにパーティション構造により結合キーごとに分割されているため、各PXセットに分散することなく結 合が可能 • ⽚⽅のみパーティション・キーと結合キーが合わなかった場合は、パーティション・キーに合わせて再分 散するパーシャル・パーティション・ワイズ結合を活⽤ 59 Copyright © 2026, Oracle and/or its affiliates
  48. パラレル実⾏関連の参考情報 マニュアル︓VLDBおよびパーティショニング・ガイド ホワイトペーパー︓Oracle Databaseでのパラレル実⾏ 津島博⼠のパフォーマンス講座 第20回,第39回 Oracle Database Technology Night

    #48 津島博⼠のパフォーマンス講座 - SQLチューニングは実⾏計画から Oracle Database Technology Night #48 津島博⼠のパフォーマンス講座 - SQLチューニングは実⾏計画から (Q&A) シバタツ流︕ パラレル・クエリーの徹底活⽤とチューニングの極意 Oracle Database Technology Night #42 Oracle Real Application Clusters 62 Copyright © 2026, Oracle and/or its affiliates