ここでは、パラレル実行環境でのパフォーマンスを向上させるためのいくつかの方法を説明します。内容は次のとおりです。
Oracle Databaseは、結果をユーザー・プロセスにパラレルで返すことはできません。問合せが多数の行を返す場合、問合せの実行は実際に速くなることもあります。ただし、ユーザー・プロセスは行の受取りをシリアルでしか実行できません。大量の結果セットを取得する問合せのパラレル実行パフォーマンスを最適化するには、PARALLEL
CREATE
TABLE
... AS
SELECT
またはダイレクト・パスINSERT
を使用して結果セットをデータベースに格納します。ユーザーは結果セットを後からシリアルで確認できます。
SELECT
をパラレルで実行してもCREATE
文には影響しません。ただし、CREATE
文がパラレルで実行される場合、オプティマイザはSELECT
もパラレルで実行しようとします。
パラレルのCREATE
TABLE
... AS
SELECT
をNOLOGGING
オプションと組み合せると、次の例のように大変効率のよい中間表機能が提供されます。
CREATE TABLE summary PARALLEL NOLOGGING AS SELECT dim_1, dim_2 ..., SUM (meas_1) FROM facts GROUP BY dim_1, dim_2;
これらの表も、パラレルINSERT
を使用して増分的にロードできます。中間表を活用するには、次の方法を使用します。
通常の副問合せは、1回計算すると、何度でも参照できます。これを利用すると、スター・スキーマに対する一部の問合せ(特に、選択のためのWHERE
句を含む述語のない問合せ)をより適切にパラレル化できるようになります。スター型変換を使用する、選択のためのWHERE
句を含む述語のあるスター問合せは、SQLを変更しなくても自動的に効率よくパラレル化できるので注意してください。
アプリケーションレベルのチェックポイントまたは再起動を実現するために、複雑な問合せを単純なステップに分解します。たとえば、1TBのデータベースに対して複雑な複数表の結合を実行すると、数十時間に及ぶ可能性があります。この問合せの最中に障害が発生すると、最初からやりなおすことになります。CREATE
TABLE
... AS
SELECT
またはPARALLEL
INSERT
AS
SELECT
を使用してこの問合せを再作成し、数時間ずつ実行される単純な問合せのシーケンスを作成します。システム障害が発生しても、最後に完了したステップの次から問合せを再起動できます。
元の表の不要な行を省いた新しい表を作成してから、元の表を削除することにより、手動パラレル削除操作を効率よく実装します。または、元の表から行を直接削除する、便利なパラレル削除機能を使用することもできます。
効率のよいマルチディメンション・ドリルダウン分析のためにサマリー表を作成します。たとえば、サマリー表には、月、種類、地域、販売担当者ごとにグループ化された収益の合計を含めることができます。
行チェーンの消去や空き領域の圧縮などを行い、古い表を新しい表にコピーして、表を再編成します。この方法はエクスポートとインポートよりも速く、再ロードよりも容易です。
新たに作成した表でオプティマイザ統計を収集するにはDBMS_STATS
パッケージを使用してください。I/Oボトルネックを回避するために、少なくともCPUと同数の物理ディスクに対してストライプ化された表領域を指定します。領域を割り当てるときに断片化を回避するために、表領域のファイル数はCPU数の倍数にする必要があります。ボトルネックの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。
EXPLAIN
PLAN
文を使用して、パラレル問合せの実行計画を表示します。EXPLAIN
PLAN
の出力で、COST
、BYTES
およびCARDINALITY
列にオプティマイザの情報が表示されます。utlxplp.sql
スクリプトを使用して、関連するすべてのパラレル情報と一緒にEXPLAIN
PLAN
出力を表示することもできます。
結合文のパラレル実行を最適化する方法がいくつかあります。システム構成を変更するか、この章で前に説明したようにパラメータを調整するか、DISTRIBUTION
ヒントなどのヒントを使用します。
EXPLAIN
PLAN
を使用する際の重要なポイントは次のとおりです。
オプティマイザの選択性見積りを確認します。問合せで1行しか生成されないとオプティマイザが予測する場合、ネステッド・ループを使用する傾向が高くなります。このとき、表が分析されていない可能性や、同一の表に対する複数の述語の相関関係についてオプティマイザの見積りが誤っている可能性があります。オプティマイザに正しい選択性を提供したり、オプティマイザに別の結合方法を使用させるために、統計やヒントを拡張することが必要な場合があります。
低カーディナリティの結合キーに対するハッシュ結合を使用します。結合キーに固有の値が少ない場合、ハッシュ結合は最適ではない可能性があります。固有値の数が並列度(DOP)を下回る場合は、一部のパラレル問合せサーバーが特定の問合せの処理を行えないことがあります。
データの偏りを考慮します。結合キーに過度のデータの偏りがある場合、ハッシュ結合を行うと、一部のパラレル問合せサーバーに多くの作業が偏る可能性があります。オプティマイザによってBROADCAST
分散方法が選択されなかった場合は、そのためのヒントの使用を検討してください。オプティマイザによってBROADCAST
分散方法が考慮されるのは、OPTIMIZER_FEATURES_ENABLE
を9.0.2以上に設定した場合のみなので注意してください。詳細は、「V$PQ_TQSTAT」を参照してください。
次の例は、オプティマイザがパラレル問合せを実行しようとする場合を示しています。
explain plan for SELECT /*+ PARALLEL */ cust_first_name, cust_last_name FROM customers c, sales s WHERE c.cust_id = s.cust_id; ---------------------------------------------------------- | Id | Operation | Name | ---------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | PX COORDINATOR | | | 2 | PX SEND QC (RANDOM) | :TQ10000 | | 3 | NESTED LOOPS | | | 4 | PX BLOCK ITERATOR | | | 5 | TABLE ACCESS FULL | CUSTOMERS | | 6 | PARTITION RANGE ALL | | | 7 | BITMAP CONVERSION TO ROWIDS| | | 8 | BITMAP INDEX SINGLE VALUE | SALES_CUST_BIX | ---------------------------------------------------------- Note ----- - Computed Degree of Parallelism is 2 - Degree of Parallelism of 2 is derived from scan of object SH.CUSTOMERS
データ・ウェアハウスに対してパラレルの挿入、更新または削除操作を使用して、データ・ウェアハウス・データベースをリフレッシュする予定があるときは、物理データベースを設計する際にさらに考慮すべき項目があります。これらの考慮事項はパラレル実行操作には影響しません。次に示す項目です。
パラレル制限に違反すると、操作はシリアルで実行されるだけです。ダイレクト・パスINSERT
制限に違反すると、APPEND
ヒントが無視され、従来の挿入操作が実行されます。エラー・メッセージは返されません。
パラレルDML itl
不変プロパティのない表(Oracle Databaseリリース9.2よりも前に作成された表、またはCOMPATIBLE
初期化パラメータを9.2
より小さい値に設定して作成された表)については、並列度(DOP)はパーティションまたはサブパーティションの数と等しくなります。つまり、表がパーティション化されていない場合、問合せはシリアルで実行されます。このプロパティのない表を確認するには、次の文を発行します。
SELECT u.name, o.name FROM obj$ o, tab$ t, user$ u WHERE o.obj# = t.obj# AND o.owner# = u.user# AND bitand(t.property,536870912) != 536870912;
トランザクション表とも呼ばれるInterested Transaction List(ITL)の詳細は、『Oracle Database概要』を参照してください。
グローバル索引がある場合、グローバル索引セグメントとグローバル索引ブロックは同じパラレルDML文のサーバー・プロセスによって共有されます。操作が同じ行に対して実行されなくても、サーバー・プロセスは同じ索引ブロックを共有できます。各サーバー・トランザクションは、索引ブロックに変更を行う前に、索引ブロック・ヘッダーの1つのトランザクション・エントリを必要とします。このため、CREATE
INDEX
文またはALTER
INDEX
文では、INITRANS
(各データ・ブロックに割り当てられるトランザクションの初期値)を、その索引に対する最大DOPなどの大きな値に設定する必要があります。
ディクショナリ管理表領域のセグメントで使用可能なトランザクション空きリスト数には制限があります。セグメントが作成されると、プロセス空きリストとトランザクション空きリストの数は固定され、変更できません。セグメント・ヘッダーでプロセス空きリストの数として大きな値を指定すると、それによって使用可能なトランザクション空きリストの数が制限されることがあります。この制限を避けるには、次にセグメント・ヘッダーを再作成するときに、プロセス空きリストの数を減らします。こうすると、セグメント・ヘッダーでトランザクション空きリストのための余裕ができます。
UPDATE
およびDELETE
操作では、各サーバー・プロセスが独自のトランザクション空きリストを必要とする場合があります。このため、パラレルDMLのDOPは、表とDML文でメンテナンスする必要があるすべてのグローバル索引に対して使用可能な、トランザクション空きリストの最小数によって事実上制限されます。たとえば、表に25のトランザクション空きリストがあるとき、その表に2つのグローバル索引があり、1つの索引に50のトランザクション空きリスト、もう1つの索引に30のトランザクション空きリストがあるとすると、DOPの制限は25になります。この表のトランザクション空きリストが40であれば、DOPの制限は30になります。
STORAGE
句のFREELISTS
パラメータは、プロセス空きリストの数を設定するために使用されます。デフォルトではプロセス空きリストは作成されません。
トランザクション空きリストのデフォルト数はブロック・サイズによって異なります。たとえば、プロセス空きリストの数が明示的に設定されない場合、デフォルトでは4KBのブロックに対して約80のトランザクション空きリストになります。トランザクション空きリストの最小数は25です。
パラレルDDLおよびパラレルDML操作は、多数のREDOログを生成する場合があります。これらのREDOログのアーカイブは、1つのARCH
プロセスでは間に合わない可能性があります。この問題を回避するため、複数のアーカイバ・プロセスを生成できます。これは、手動で行うこともジョブ・キューを使用して行うこともできます。
パラレルDML操作により、短時間でバッファ・キャッシュ内の多数のデータ、索引およびUNDOブロックの内容が使用されます。たとえば、次の構文でV$SYSTEM_EVENT
ビューを問い合せると、free_buffer_waits
の値が高く示されると想定します。
SELECT TOTAL_WAITS FROM V$SYSTEM_EVENT WHERE EVENT = 'FREE BUFFER WAITS';
この場合は、DBWnプロセスを増やすことの検討が必要です。空きバッファの待機時間がない場合、問合せによって行が返されません。
[NO]LOGGING
句は、表、パーティション、表領域および索引に適用されます。NOLOGGING
句を使用すると、事実上、特定の操作(ダイレクト・パスINSERT
など)に対してログが生成されません。NOLOGGING
属性はINSERT
文のレベルでは指定されませんが、表、パーティション、索引または表領域に対してALTER
文またはCREATE
文を使用して指定されます。
表または索引にNOLOGGING
が設定されると、パラレルまたはシリアルのダイレクト・パスINSERT
操作ではREDOログが生成されません。NOLOGGING
オプションが設定されて実行しているプロセスは、REDOが生成されないため、処理が速くなります。ただし、表、パーティションまたは索引に対するNOLOGGING
操作の後、バックアップを実行する前にメディア障害が発生すると、変更されたすべての表、パーティションおよび索引が破損することがあります。
NOLOGGING
句が使用されている場合、ダイレクト・パスINSERT
操作(ディクショナリ更新以外)では、REDOログは常に生成されません。NOLOGGING
属性はUNDOには影響せず、REDOのみに影響します。正確には、NOLOGGING
を使用すると、ダイレクト・パスINSERT
操作ではごくわずかのREDO(フル・イメージREDOとは逆のレンジ無効REDO)が生成されます。
下位互換性のため、CREATE
TABLE
文での代替キーワードとして[UN]RECOVERABLE
も引き続きサポートされています。ただし、この代替キーワードは今後のリリースでサポートが終了する可能性があります。
表領域レベルでは、LOGGING句によって、その表領域に作成されるすべての表、索引およびパーティションのデフォルト・ロギング属性が指定されます。既存の表領域のロギング属性がALTER
TABLESPACE
文によって変更されると、ALTER
文の後で作成されたすべての表、索引およびパーティションには新しいロギング属性が適用されます。既存の表、索引、パーティションのロギング属性は変化しません。表領域レベルのロギング属性は、表、索引またはパーティション・レベルの指定で上書きできます。
デフォルトのロギング属性はLOGGING
です。ただし、ALTER
DATABASE
NOARCHIVELOG
を発行してデータベースをNOARCHIVELOG
モードにした場合、ロギング属性の指定にかかわらず、ロギングなしで実行できるすべての操作ではログが生成されなくなります。
複数のプロセスが同時に作動して、1つの索引を作成できます。索引を作成するために必要な処理を複数のサーバー・プロセスに分割することで、Oracle Databaseでは、1つのサーバー・プロセスによって索引をシリアルで作成した場合に比べて速く索引を作成できます。
パラレル索引作成では、ORDER
BY
句での表スキャンとほぼ同様の処理が行われます。表がランダムにサンプリングされ、索引をDOPと同数に均等に分割するための索引キーのセットが検出されます。問合せプロセスの第1セットが表をスキャンしてキーと行IDのペアを抽出し、問合せプロセスの第2セットのプロセスに対してキーに基づいて各ペアを送ります。第2セットの各プロセスは、キーをソートし、通常の方法で索引を構築します。索引のすべての部分が構築されると、パラレル実行コーディネータが各部(ソート済)を連結して、最終的に索引を形成します。
パラレルのローカル索引作成では、1つのサーバー・セットが使用されます。セットの各サーバー・プロセスは、割り当てられた表パーティションをスキャンし、そのパーティションに対して索引パーティションを構築します。所定のDOPに対して半数のサーバー・プロセスが使用されるため、パラレルのローカル索引作成が可能になるのはDOPが高い場合です。ただし、DOPは作成する索引パーティション数以内に制限されます。この制限を回避するには、DBMS_PCLXUTIL
パッケージを使用できます。
索引作成時にREDOおよびUNDOのロギングを行わないことをオプションで指定できます。こうすると、パフォーマンスが大きく向上する可能性がありますが、索引が一時的にリカバリ不可の状態になります。新しい索引のバックアップを取得すると、リカバリは可能になります。アプリケーションで、索引のリカバリ時に索引を再作成する時間が許容される場合は、NOLOGGING
句の使用を検討してください。
CREATE
INDEX
文のPARALLEL
句のみが、索引作成のDOPを指定するただ1つの方法です。DOPがCREATE
INDEX
文のPARALLEL句に指定されないと、CPUの数がDOPとして使用されます。PARALLEL
句がない場合、索引作成はシリアルで行われます。
索引をパラレルで作成するとき、STORAGE
句には、問合せサーバー・プロセスで作成される各副索引の記憶域を指定します。このため、INITIAL
値が5MB、DOPが12で作成される索引は、索引作成時に少なくとも60MBの記憶域を消費します。各プロセスが5MBのエクステントで開始するためです。問合せコーディネータ・プロセスがソート済の副索引を結合するときに、エクステントの一部が切り捨てられ、生成される索引はリクエストの60MBよりも小さくなることがあります。
UNIQUE
またはPRIMARY
KEY
制約を表に追加するか、有効にすると、必要な索引をパラレルで自動的に作成できなくなります。かわりに、CREATE
INDEX
文と適切なPARALLEL
句を使用して、必要な列に対して手動で索引を作成します。こうすることで、制約を有効にするか追加するときに、Oracle Databaseが既存の索引を使用します。
同じ表の複数の制約を同時にパラレルで有効にできるのは、すべての制約がすでにENABLE
NOVALIDATE
状態になっている場合です。次の例では、ALTER
TABLE
... ENABLE
CONSTRAINT
文が、制約をパラレルでチェックする表スキャンを実行します。
CREATE TABLE a (a1 NUMBER CONSTRAINT ach CHECK (a1 > 0) ENABLE NOVALIDATE) PARALLEL; INSERT INTO a values (1); COMMIT; ALTER TABLE a ENABLE CONSTRAINT ach;
ここでは、パラレルDML機能の概要を説明します。内容は次のとおりです。
関連項目:
|
INSERT
文を使用して実行できる機能は表8-5にまとめられます。
表8-5 INSERT機能のまとめ
挿入の種類 | パラレル | シリアル | NOLOGGING |
---|---|---|---|
従来型 |
不可 パラレルDMLを有効にして |
可能 |
不可 |
ダイレクト・パス
( |
可能(次の指定が必要)
さらに、次のいずれか1つの指定
または次の指定 強制的に |
可能(次の指定が必要)
|
可能(次の指定が必要) パーティションまたは表に対する |
パラレルDMLが有効で、PARALLEL
ヒントがあるか PARALLEL
属性がデータ・ディクショナリの表に設定されている場合、制限が適用されないかぎり挿入操作はパラレルで行われ追加されます。PARALLEL
ヒントまたはPARALLEL
属性のいずれかがない場合、挿入操作はシリアルで行われます。自動DOPでは、パラレルDMLが有効化または強制される場合にかぎり、SQL文のDML部分のみがパラレル化されることに注意してください。
パラレルDMLが有効化される場合は、NOAPPEND
ヒントを使用してパラレルの従来型挿入操作を実行できます。たとえば、/*+
noappend
parallel
*/
をSQL INSERT
文で使用して、パラレルの従来型挿入を実行できます。
SQL> INSERT /*+ NOAPPEND PARALLEL */ INTO sales_hist SELECT * FROM sales;
パラレルの従来型挿入操作の利点は、ダイレクト・パスINSERT
の制約なしにオンライン操作を実行できることです。パラレルの従来型挿入操作の欠点は、ダイレクト・パスINSERT
よりもプロセスの速度が遅いことです。
パラレル挿入操作では追加モードはデフォルトです。つまり、データは必ず表に割り当てられる新しいブロックに挿入されます。このため、APPEND
ヒントはオプションです。追加モードは、INSERT
操作の速度を速める場合には使用しますが、領域の使用率の最適化が必要な場合は使用しないでください。NOAPPEND
を使用すると追加モードを上書きできます。
APPEND
ヒントは、シリアルとパラレル両方の挿入操作に適用されます。このヒントを使用すると、シリアル挿入の処理時間も短縮されます。ただし、APPEND
は多くの領域を使用する必要があり、ロックのオーバーヘッドも増加します。
NOLOGGING
とAPPEND
を一緒に使用すると、プロセスはさらに速くなります。NOLOGGING
は操作のREDOログが生成されないことを意味します。NOLOGGING
はデフォルトではありません。パフォーマンスを最適化するときに使用します。表またはパーティションのリカバリが必要となる通常の場合には使用しないでください。リカバリが必要な場合は、操作の直後にバックアップを取得するようにします。ALTER
TABLE
[NO]LOGGING
文を使用して、適切な値を設定します。
データ・ディクショナリで表またはパーティションにPARALLEL
属性があるとき、この属性設定が、INSERT
文、UPDATE
文、DELETE
文および問合せでの並列処理を決定するために使用されます。文での表に対する明示的なPARALLEL
ヒントは、データ・ディクショナリのPARALLEL
属性の効果よりも優先されます。
NO_PARALLEL
ヒントを使用すると、データ・ディクショナリの表のPARALLEL
属性を上書きできます。一般的にヒントは属性よりも優先されます。
DML操作の並列処理が考慮されるのは、セッションがPARALLEL
DML
有効モードになっている場合のみです。(このモードにするには、ALTER
SESSION
ENABLE
PARALLEL
DML
を使用します。)このモードは、問合せまたはDML文の問合せ部分の並列処理には影響しません。
INSERT
... SELECT
文では、INSERT
キーワードの後にPARALLEL
ヒントを指定できます。このヒントはSELECT
キーワードの後にも指定できます。INSERT
キーワードの後のPARALLEL
ヒントはINSERT
操作のみに適用され、SELECT
キーワードの後のPARALLEL
ヒントはSELECT
操作のみに適用されます。したがって、INSERT
操作とSELECT
操作の並列処理は互いに独立しています。一方の操作をパラレルで実行できなくても、もう一方の操作をパラレルで実行できるかどうかには影響しません。
ユーザーがパラレルDMLをセッションで明示的に有効化した場合、および関連する表にデータ・ディクショナリ・エントリでPARALLEL
属性が設定されている場合、挿入操作をパラレル化できる機能により既存の動作が変更されます。この場合、選択操作がパラレル化された既存のINSERT
... SELECT
文で、挿入操作もパラレル化できます。
複数の表を問い合せる場合は、複数のSELECT
PARALLEL
ヒントと複数のPARALLEL
属性を指定できます。
例8-10に、ACME
の買収後に雇用された新しい従業員の追加を示します。
PARALLEL
ヒント(UPDATE
またはDELETE
キーワードの直後に指定)は、基礎となるスキャン操作に適用されるだけではなく、UPDATE
またはDELETE
操作にも適用されます。または、変更対象の表の定義に指定されるPARALLEL
句で、UPDATE
またはDELETE
のパラレル化を指定できます。
セッションまたはトランザクションについてパラレルDMLを明示的に有効化した場合、問合せ操作がパラレル化されたUPDATE
文またはDELETE
文は、UPDATE
操作またはDELETE
操作もパラレル化できます。文の副問合せまたは更新可能ビューには、独自のPARALLEL
ヒントまたは句を指定できますが、これらのパラレル・ディレクティブは更新または削除をパラレル化する決定には影響しません。これらの操作をパラレルで実行できなくても、UPDATE
またはDELETE
部分をパラレルで実行できるかどうかには影響しません。
例8-11に、ダラスのすべての店員を10%昇給する更新操作を示します。
例8-11 UPDATEとDELETEのパラレル化
UPDATE /*+ PARALLEL(employees) */ employees SET SAL=SAL * 1.1 WHERE JOB='CLERK' AND DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOCATION='DALLAS');
PARALLEL
ヒントは、UPDATE
操作とスキャンに適用されます。
例8-12には、食料品カテゴリのすべての商品の削除を示します。最近、食料品事業が別会社として分離されたためです。
パラレルDMLを更新可能結合ビュー機能と組み合せると、データ・ウェアハウス・システムの表をリフレッシュするための効率のよいソリューションが得られます。表をリフレッシュするには、OLTP本番システムで生成される差分データを使用して更新します。
次の例では、列c_key
、c_name
およびc_addr
を含むcustomer
という表をリフレッシュするとします。差分データには、新しい行またはデータ・ウェアハウスの最後のリフレッシュ以降に更新された行が含まれます。この例では、本番システムの更新データはデータ・ウェアハウス・システムにASCIIファイルとして送られます。リフレッシュ・プロセスを開始する前に、これらのファイルを一時表diff_customer
にロードする必要があります。このタスクを効率よく実行するには、パラレル・オプションとダイレクト・オプションの両方を指定したSQL*Loaderを使用できます。パラレルでロードする場合はAPPEND
ヒントも使用します。
diff_customer
がロードされたら、リフレッシュ・プロセスを開始できます。これは、次に示すように、2フェーズで実行するか、パラレルでのマージにより実行することができます。
次の文は、副問合せを使用して更新する単純なSQLの実装です。
UPDATE customers SET(c_name, c_addr) = (SELECT c_name, c_addr FROM diff_customer WHERE diff_customer.c_key = customer.c_key) WHERE c_key IN(SELECT c_key FROM diff_customer);
残念ながら、この文の2つの副問合せはパフォーマンスに影響します。
かわりに、更新可能結合ビューを使用してこの問合せを作成しなおすことができます。問合せを再作成するには、まず主キー制約をdiff_customer
表に追加して、変更される列がキー保存表にマップされるようにします。
CREATE UNIQUE INDEX diff_pkey_ind ON diff_customer(c_key) PARALLEL NOLOGGING; ALTER TABLE diff_customer ADD PRIMARY KEY (c_key);
その後、次のSQL文を使用してcustomers
表を更新できます。
UPDATE /*+ PARALLEL(cust_joinview) */ (SELECT /*+ PARALLEL(customers) PARALLEL(diff_customer) */ CUSTOMER.c_name AS c_name CUSTOMER.c_addr AS c_addr, diff_customer.c_name AS c_newname, diff_customer.c_addr AS c_newaddr FROM diff_customer WHERE customers.c_key = diff_customer.c_key) cust_joinview SET c_name = c_newname, c_addr = c_newaddr;
結合ビューcust_joinview
にデータを提供するための基本スキャンはパラレルで実行されます。その後、更新をパラレル化して、さらにパフォーマンスを向上させることができます。ただし、これはcustomers
表がパーティション化されている場合のみです。
リフレッシュ・プロセスの後半のフェーズでは、diff_customer
一時表の新しい行をcustomers
表に挿入します。更新の場合とは異なり、INSERT
文の副問合せの指定は必要です。
INSERT /*+PARALLEL(customers)*/ INTO customers SELECT * FROM diff_customer s);
ただし、HASH_AJ
ヒントを使用すると、この副問合せは必ずアンチハッシュ結合に変換されます。こうすると、パラレルINSERT
を使用して、前の文を効率よく実行できます。パラレルINSERT
は、表がパーティション化されていなくても適用できます。
更新と挿入を組み合せて1つの文にすることができます。これは一般的にはマージと呼ばれます。次の文は、「パラレルでの表の更新」と「パラレルでの表への新しい行の挿入」のすべての文と同じ結果を生成します。
MERGE INTO customers USING diff_customer ON (diff_customer.c_key = customer.c_key) WHEN MATCHED THEN UPDATE SET (c_name, c_addr) = (SELECT c_name, c_addr FROM diff_customer WHERE diff_customer.c_key = customers.c_key) WHEN NOT MATCHED THEN INSERT VALUES (diff_customer.c_key,diff_customer.c_data);