7 マテリアライズド・ビューのリフレッシュ
この章では、データ・ウェアハウス環境でマテリアライズド・ビューを使用する際に良好なパフォーマンスおよびデータの整合性を維持する主要な要素である、マテリアライズド・ビューのリフレッシュ方法について説明します。
この章の内容は次のとおりです。
7.1 マテリアライズド・ビューのリフレッシュについて
データベースでは、実表の変更後にマテリアライズド・ビューをリフレッシュして、マテリアライズド・ビューのデータを管理します。
リフレッシュ操作の実行には、索引再構築のための一時領域が必要で、リフレッシュ操作そのものを実行するために追加の領域が必要な場合もあります。サイトによっては、マテリアライズド・ビューを同時にすべてリフレッシュすることが適切ではない場合もあります。ベースとなるディテール・データが更新されると、このデータを使用するすべてのマテリアライズド・ビューが失効します。したがって、マテリアライズド・ビューのリフレッシュを遅延させる場合は、選択したリライトの整合性レベルを信頼して、失効したマテリアライズド・ビューがクエリー・リライトに使用できるかどうかを判断するか、または、ALTER
SYSTEM
SET
QUERY_REWRITE_ENABLED = FALSE
文でクエリー・リライトを一時的に使用禁止にできます。マテリアライズド・ビューのリフレッシュ後に、ALTER
SYSTEM
SET
QUERY_REWRITE_ENABLED
にTRUE
を指定すると、現行のデータベース・インスタンスにあるすべてのセッションに対して、クエリー・リライトをデフォルトの状態である使用可能に戻すことができます。マテリアライズド・ビューをリフレッシュすると、そのすべての索引が自動的に更新されます。完全リフレッシュの場合は、リフレッシュ中にすべての索引を再作成できるように、一時ソート領域が必要です。これは、完全リフレッシュでは、新しいデータ・ボリューム全体が挿入される前に表が切り捨てられるか、削除されるためです。索引再作成のための一時領域が不足している場合は、リフレッシュ操作の前に明示的に各索引を削除するか、UNUSABLE
マークを付ける必要があります。
マテリアライズド・ビューのリフレッシュのタイプについて
- ログベースのリフレッシュ
- パーティション・チェンジ・トラッキング(PCT)リフレッシュ
- 論理パーティション・チェンジ・トラッキング(LPCT)リフレッシュ
実表に対するパーティション・メンテナンス操作(PMOPS)がある場合、使用可能な増分リフレッシュ方法はPCTのみです。
増分リフレッシュは、一般にFAST
リフレッシュと呼ばれます。これは、通常は完全リフレッシュよりも高速に実行されるためです。
完全リフレッシュは、マテリアライズド・ビューをBUILD
IMMEDIATE
で定義した場合に、最初に作成するときに実行されます。ただし、そのマテリアライズド・ビューが事前作成表を参照する場合、またはBUILD
DEFERRED
で定義された場合は除きます。ユーザーは、マテリアライズド・ビューを作成した後いつでも完全リフレッシュを実行できます。完全リフレッシュを実行すると、マテリアライズド・ビューを定義する問合せも実行されます。この処理は、特にデータベースが大量のデータを読み取って処理する必要がある場合に遅くなることがあります。
増分リフレッシュにより、マテリアライズ・ビューを最初から再作成する必要がなくなります。このように、変更のみを処理するため、リフレッシュ時間を大幅に削減できます。マテリアライズド・ビューは、必要時に、または定期的にリフレッシュできます。また、実表と同じデータベース内のマテリアライズド・ビューは、トランザクションによって実表の変更がコミットされるたびにリフレッシュできます。
ログベースの高速リフレッシュ方法を使用する場合、実表に対する変更はマテリアライズド・ビュー・ログまたはダイレクト・ローダー・ログに記録されます。マテリアライズド・ビュー・ログは、実表への変更を記録するスキーマ・オブジェクトであるため、実表で定義されているマテリアライズド・ビューを増分リフレッシュできます。マテリアライズド・ビュー・ログは、それぞれ1つの実表に関連付けられています。マテリアライズド・ビュー・ログは、実表と同じデータベースおよびスキーマに格納されます。
LPCTはPCTと似ていますが、LPCTには、実表に対する物理パーティション化ではなく論理パーティション化方法が必要です。PCT対応のマテリアライズド・ビューの場合と同様に、LPCT対応のマテリアライズド・ビューでは、リフレッシュ操作にマテリアライズド・ビュー・ログは必要ありません。マテリアライズド・ビューが定義されている実表は、キー範囲を使用して論理的にパーティション化されます。LPCTパーティション化キーを使用する表には物理パーティション化がないため、LPCTキー範囲に属する表の行は、別個の物理パーティションに分離されません。実表は、物理的にパーティション化しないか、論理パーティション・キーとは異なるキーで物理的にパーティション化することができます。
PCTリフレッシュ方法は、変更された実表がパーティション化されている場合に使用でき、変更された実表のパーティションを使用して、マテリアライズド・ビュー内の影響を受けるパーティションまたはデータの部分を識別することができます。この方法では、影響を受けるマテリアライズド・ビュー・パーティション内のすべてのデータ、またはデータのうちの影響を受ける部分が削除され、ゼロから再計算されます。
なお、表がすでに物理的にパーティション化されている場合は、LPCTを同じ物理パーティション化キーで定義できません。また、LPCTリフレッシュを再度使用するには、まず表に対するPMOPSで完全リフレッシュが必要になります。
マテリアライズド・ビューのリフレッシュ・モードについて
マテリアライズド・ビューを作成する場合、リフレッシュをON
DEMAND
で行うか、ON
COMMIT
で行うかを指定できます。
マテリアライズド・ビューで参照される表に対する挿入、更新または削除操作が、そのマテリアライズド・ビューのリフレッシュと同時に実行されると予想され、そのマテリアライズド・ビューに結合と集計が含まれている場合は、ON
DEMAND
高速リフレッシュではなくON
COMMIT
高速リフレッシュを使用することをお薦めします。
ON
COMMIT
の場合は、トランザクションがコミットされるたびに、マテリアライズド・ビューが変更されます。このため、マテリアライズド・ビューに常に最新データが含まれていることが保証されます。または、ON
DEMAND
を指定すると、マテリアライズド・ビューのリフレッシュが発生する時期を制御できます。ON
DEMAND
マテリアライズド・ビューの場合、リフレッシュはDBMS_SYNC_REFRESH
パッケージまたはDBMS_MVIEW
パッケージで提供されるリフレッシュ方法で実行できます。
-
DBMS_SYNC_REFRESH
パッケージには、同期リフレッシュのAPIが含まれています。詳細は、同期リフレッシュを参照してください。 -
DBMS_MVIEW
パッケージに含まれるAPIの使用方法については、この章で説明します。リフレッシュ操作の基本タイプには、完全リフレッシュ、高速リフレッシュ、パーティション・チェンジ・トラッキング(PCT)リフレッシュの3つがあります。
DBMS_MVIEW
パッケージには、リフレッシュ操作を実行するための3つのAPIが含まれています。
-
DBMS_MVIEW.REFRESH
1つまたは複数のマテリアライズド・ビューをリフレッシュします。
-
DBMS_MVIEW.REFRESH_ALL_MVIEWS
すべてのマテリアライズド・ビューをリフレッシュします。
-
DBMS_MVIEW.REFRESH_DEPENDENT
特定のプライマリ表またはマテリアライズド・ビュー、あるいはプライマリ表やマテリアライズド・ビューのリストに依存するマテリアライズド・ビューをすべてリフレッシュします。
マテリアライズド・ビューのリフレッシュ方法
これらの各リフレッシュ・オプションに対して、リフレッシュの実行方法に関する2つの技法、つまり、ホーム内リフレッシュとホーム外リフレッシュがあります。ホーム内リフレッシュは、マテリアライズド・ビューに対して直接リフレッシュ文を実行します。ホーム外リフレッシュは1つ以上の外部表を作成し、その外部表に対してリフレッシュ文を実行し、次にマテリアライズド・ビューまたは影響を受けるマテリアライズド・ビューのパーティションをその外部表で切り替えます。ホーム内リフレッシュとホーム外リフレッシュは両方とも、特定のリフレッシュ・シナリオで優れたパフォーマンスを発揮します。ただし、ホーム外リフレッシュを使用すると、リフレッシュ時、特にリフレッシュ文を完了するのに時間がかかる場合に、マテリアライズド・ビューの高可用性が実現されます。
同期リフレッシュと呼ばれるホーム外メカニズムは、ファクト表とそれらのマテリアライズド・ビューの両方が同じ方法でパーティション化されている場合、またはそれらのパーティションが機能依存性によって関連付けられている場合の、データ・ウェアハウスの一般的な使用シナリオを対象としています。
このリフレッシュ・アプローチにより、一連の表と表に定義されているマテリアライズド・ビューが、常に同期した状態を維持できます。このリフレッシュ方法では、ユーザーは、実表の内容を直接変更するのではなく、整合性を確保するために、実表とマテリアライズド・ビューに同時にこれらの変更を適用する、同期リフレッシュ・パッケージによって提供されるAPIを使用する必要があります。同期リフレッシュ方法は、増分データのロードが厳密に制御され、定期的に発生するデータ・ウェアハウスには非常に適しています。
関連項目:
7.1.1 マテリアライズド・ビューの完全リフレッシュについて
完全リフレッシュは、マテリアライズド・ビューを最初にBUILD
IMMEDIATE
で定義した場合に実行されます。ただし、そのマテリアライズド・ビューが事前作成表を参照する場合は除きます。BUILD
DEFERRED
を使用するマテリアライズド・ビューの場合は、初めて使用する前に完全リフレッシュを実行する必要があります。完全リフレッシュは、どのマテリアライズド・ビューの場合も必要に応じて要求できます。このリフレッシュでは、ディテール表が読み込まれ、マテリアライズド・ビューの結果が計算されます。これは、読み込まれて処理されるデータが大量の場合には、時間がかかる処理です。そのため、完全リフレッシュを要求する前に、必ずその処理時間を考慮してください。
また、すでに作成済のマテリアライズド・ビューが次の項で説明する高速リフレッシュの条件を満たしていないために、完全リフレッシュしか使用できない場合もあります。
7.1.2 マテリアライズド・ビューの高速リフレッシュについて
ほとんどのデータ・ウェアハウスでは、そのディテール・データが定期的に増分更新されます。マテリアライズド・ビューのスキーマ・デザインについてで説明しているように、SQL*Loaderまたはバルク・ロード・ユーティリティを使用して、ディテール・データの増分ロードを実行できます。通常、マテリアライズド・ビューの高速リフレッシュは効率的です。これは、すべてのマテリアライズド・ビューを再計算するのではなく、変更分のみが既存のデータに適用されるためです。このように、変更のみを処理するため、リフレッシュ時間を大幅に削減できます。
7.1.3 マテリアライズド・ビューのパーティション・チェンジ・トラッキング(PCT)リフレッシュについて
パーティション・チェンジ・トラッキングは、マテリアライズド・ビューのより効率的なマテリアライズド・リフレッシュのために、マテリアライズド・ビューに含まれる表の個々のパーティション内の変更に関する知識を活用する機能です。
ディテール表に対するパーティション・メンテナンス操作がある場合、高速リフレッシュにはパーティション・チェンジ・トラッキングのみを使用できます。マテリアライズド・ビューに対するPCTベースのリフレッシュは、パーティション・チェンジ・トラッキングについてで説明しているすべての条件を満たした場合にのみ有効です。
ディテール表に対するパーティション・メンテナンス操作がない場合、DBMS_MVIEW
パッケージのプロシージャでリフレッシュのFAST
メソッド(method => 'F'
)を要求すると、PCTリフレッシュが選択される前に、ログベースのルールの高速リフレッシュを試行するヒューリスティックなルールが使用されます。同様に、FORCE
メソッド(method => '?'
)を要求すると、ログベースの高速リフレッシュ、PCTリフレッシュ、LPCTリフレッシュ、完全リフレッシュの順番でリフレッシュ方法が選択されます。または、PCTメソッド(method => 'P'
)を要求することもできます。Oracleは、すべてのPCT要件が満たされている場合はPCTメソッドを使用します。
マテリアライズド・ビューのパーティション化によるメリットで説明されている条件を満たしており、PCTリフレッシュ・プロセスを効率的に実行できる場合は、マテリアライズド・ビューに対してTRUNCATE
PARTITION
を使用できます。
関連項目:
-
パーティション・チェンジ・トラッキングの詳細は、パーティション・チェンジ・トラッキングについてを参照してください。
7.1.4 マテリアライズド・ビューの論理パーティション・チェンジ・トラッキング(LPCT)リフレッシュについて
論理パーティション・チェンジ・トラッキングは、マテリアライズド・ビューのより効率的なマテリアライズド・リフレッシュのために、マテリアライズド・ビューに含まれる表の個々の論理パーティション内の変更に関する知識を活用する機能です。表の物理パーティション化に依存するパーティション・チェンジ・トラッキングとは異なり、表の既存のパーティション化スキーマまたは存在しないパーティション化スキーマとは関係なく、表の論理パーティションを定義します。
LPCTでは、マテリアライズド・ビューの失効性を論理パーティションの粒度で追跡できるため、マテリアライズド・ビューの一部が失効している場合でも、クエリー・リライト・エンジンで、そのマテリアライズド・ビューの最新の論理パーティション内のデータを使用できます。その結果、それらのマテリアライズド・ビューはより使いやすくなります。実際の多くのアプリケーションでは、この結果、きめ細かなクエリー・リライトにより、問合せパフォーマンスが大幅に向上しています。LPCTでは、失効した論理パーティションのみを対象としてリフレッシュ操作を実行できます。これにより、データすべてが再ロードされることがなくなります。
LPCTを使用しない場合、非パーティション表にあるマテリアライズド・ビューは、完全に失効しているか完全に最新かのどちらかです。マテリアライズド・ビューが失効していると判断された場合、問合せで必要とされているデータが最新である可能性があっても、そのマテリアライズド・ビューはクエリー・リライトには使用できません。
LPCTの追跡メカニズムでは、指定されたLPCTキーに基づいて変更統計が記録され統合されます。隣接する変更データは、論理パーティションにグループ化されます。リフレッシュ中には、マテリアライズド・ビュー・ログが使用されるのではなく、LPCTによって論理パーティション内の変更点が調べられます。これらは、単一の列、およびRANGEまたはINTERVAL論理パーティションに限定されます。LPCTにより、実表のパーティション化が強制されることはありません。この機能では、新しいディクショナリ表にある定義済のRANGEまたはINTERVALパーティション内の変更点が追跡されます。LPCTリフレッシュを使用してマテリアライズド・ビューをリフレッシュするための構文は次のとおりです。
execute DBMS_MVIEW.REFRESH(<mview_name>,'L');
PCTとは異なり(これは表作成時に指定する必要がある)、LPCTは、表作成に関係なく、いつでも実表で作成、変更または削除できます。実表はパーティション化または非パーティション化できます。このため、PCTより適応性が高くなります。LPCTフレームワークでは、メタデータのみが必要であり、実表に対する変更はないため、PCTよりも物理的なオーバーヘッドが少なくなります。LPCTでは、PCTと組み合せることで、よりきめ細かく失効範囲を特定でき、より多くのクエリー・リライト、およびより高速なマテリアライズド・ビュー・リフレッシュが可能になります。実表が物理的にパーティション化されており、かつ別のパーティション化キーで定義されているLPCTも含む場合は、DBMS_MVIEW.REFRESH()
のコールで'L'
オプションを指定することで、LPCTとPCTを組み合せた方法を使用して依存マテリアライズド・ビューをリフレッシュできます。
トラッキングにおいては、LPCTにより実表にある変更された各行が記録されることはないため、LPCTはマテリアライズド・ビュー・ログよりも軽量になります。最新データのためにマテリアライズド・ビュー・ログ全体をスキャンし実表と結合する必要がないため、LPCTリフレッシュでは、特に、変更された行が比較的大きい場合には、ログベースの高速リフレッシュよりもパフォーマンスが高くなります。
論理パーティション・チェンジ・トラッキング(LPCT)では、変更された行が比較的大きい場合に、ログベースのリフレッシュのパフォーマンスがより高くなります。LPCTリフレッシュをログベースのリフレッシュと組み合せると、より的確な行が対象となることで効率がさらに向上します。
関連項目:
-
パーティション・チェンジ・トラッキングの詳細は、パーティション・チェンジ・トラッキングについてを参照してください。
- 実表の論理パーティションに対応している失効性を確認するためのビューについては、『Oracle Databaseリファレンス』の
USER_MVIEW_DETAIL_LOGICAL_PARTITION
を参照してください。また、ALL_MVIEW_DETAIL_LOGICAL_PARTITION
およびDBA_MVIEW_DETAIL_LOGICAL_PARTITION
の対応する説明を参照してください。 - 論理パーティションとともにDBMS_MVIEWパッケージを使用する方法の詳細は、PL/SQLパッケージおよびタイプ・リファレンスの
DBMS_MVIEW
を参照してください。
7.1.5 ホーム外リフレッシュ・オプションについて
Oracle Database 12cリリース1より、マテリアライズド・ビューのリフレッシュ・パフォーマンスおよび可用性を向上させる新しいリフレッシュ・オプションが利用可能となります。このリフレッシュ・オプションはホーム外リフレッシュと呼ばれます。これは、マテリアライズド・ビューのコンテナ表に直接変更を適用する既存のホーム内リフレッシュとは対照的に、リフレッシュの際に外部表を使用するためです。ホーム外リフレッシュ・オプションは、FAST
('F'
)、COMPLETE
('C'
)、PCT
('P'
)、FORCE
('?'
)など、既存のすべてのリフレッシュ方法とともに使用できます。ホーム外リフレッシュは特に、従来のDML文ではうまく対応できない大量のデータ変更を伴う状況を処理する際に効果的です。また、リフレッシュされるマテリアライズド・ビューは、リフレッシュ文の実行の際にダイレクト・アクセスおよびクエリー・リライトに使用できるため、非常に高い可用性を得ることができます。さらに、マテリアライズド・ビューのコンテナ表が徐々に断片化されたり、リフレッシュの中間結果が表示されるなどの問題の可能性を回避するのにも役立ちます。
ホーム外リフレッシュでは、マテリアライズド・ビューの全体または影響を受ける部分は、1つ以上の外部表に計算されます。パーティション化されたマテリアライズド・ビューの場合、パーティション・レベルのチェンジ・トラッキングが可能で、マテリアライズド・ビューにローカル索引が定義されていれば、ホーム外の方法では外部表にも同じローカル索引が構築されます。このリフレッシュ・プロセスは、マテリアライズド・ビューと外部表の切替え、または影響を受けるパーティションと外部表とのパーティション交換により行われます。切替えまたはパーティション交換操作中にクエリー・リライトがサポートされないことに注意してください。リフレッシュの間、外部表には効率的なダイレクト・ロードによって移入が行われます。
この項では、次の項目について説明します。
7.1.5.1 ホーム外リフレッシュのタイプ
ホーム外リフレッシュには次の3つのタイプがあります。
-
ホーム外高速リフレッシュ
これは、ホーム内高速リフレッシュより高い可用性を提供します。また、変更がマテリアライズド・ビューの多くの部分に影響を与える場合には、より良好なパフォーマンスが得られます。
-
ホーム外PCTリフレッシュ
これは、ホーム内PCTリフレッシュより高い可用性を提供します。パーティション化されたマテリアライズド・ビューおよびパーティション化されていないマテリアライズド・ビューには、2つの異なるアプローチがあります。切捨ておよびダイレクト・ロードが実現可能ではない場合、変更が比較的大規模であればホーム外リフレッシュを使用する必要があります。切捨ておよびダイレクト・ロードが実現可能な場合、パフォーマンスの観点からは、ホーム内リフレッシュをお薦めします。可用性の観点からは、望ましいのは常にホーム外リフレッシュです。
-
ホーム外完全リフレッシュ
これは、ホーム内完全リフレッシュより高い可用性を提供します。
DBMS_MVIEW
パッケージのリフレッシュ・インタフェースをmethod
=
?
およびout_of_place
=
true
と指定して使用すると、まずホーム外高速リフレッシュが試みられ、次にホーム外PCTリフレッシュ、最後にホーム外完全リフレッシュが試みられます。次に例を示します。
DBMS_MVIEW.REFRESH('CAL_MONTH_SALES_MV', method => '?', atomic_refresh => FALSE, out_of_place => TRUE);
7.1.5.2 ホーム外リフレッシュの制限および考慮事項
ホーム外リフレッシュには、対応するホーム内リフレッシュを使用する場合に適用されるすべての制限が適用されます。また、これには、次の制限があります。
-
マテリアライズド結合ビューおよびマテリアライズド集計ビューのみが使用可能です。
-
ON
COMMIT
リフレッシュは使用できません。 -
リモート・マテリアライズド・ビュー、キューブ・マテリアライズド・ビュー、オブジェクト・マテリアライズド・ビューは使用できません。
-
LOB
列は使用できません。 -
マテリアライズド・ビューでマテリアライズド・ビューのログ、トリガーまたは制約(
NOT
NULL
を除く)が定義されている場合、使用できません。 -
マテリアライズド・ビューが
CLUSTERING
句を含む場合、使用できません。 -
マテリアライズド・ビューにセキュリティ・ポリシーが定義されている場合、許可されません。
-
CREATE
またはALTER
MATERIALIZED
VIEW
セッション、またはALTER
TABLE
セッション内の完全リフレッシュには適用されません。 -
アトミック・モードは使用できません。
atomic_refresh
をTRUE
に指定し、out_of_place
をTRUE
に指定すると、エラーが表示されます。
ホーム外PCTリフレッシュには、次の制限があります。
-
UNION
ALL
やグルーピング・セットは使用できません。
ホーム外高速リフレッシュには、次の制限があります。
-
UNION
ALL
、グルーピング・セットおよび外部結合は使用できません。 -
複数の表が複合DML文で変更されている場合、マテリアライズド結合ビューでは使用できません。
ホーム外リフレッシュでは、リフレッシュの間の外部表および索引用に追加の記憶域が必要です。したがって、使用可能な表領域が十分にあるか、自動拡張がオンになっている必要があります。
ホーム外PCTリフレッシュのパーティション交換は、マテリアライズド・ビューのグローバル索引に影響を及ぼします。したがって、マテリアライズド・ビューのコンテナ表にグローバル索引が定義されている場合、Oracleでは、パーティション交換の前にグローバル索引を無効にし、パーティション交換の後でグローバル索引を再構築します。この再構築はさらなるオーバーヘッドとなります。
7.1.6 マテリアライズド・ビューのON COMMITリフレッシュについて
ON
COMMIT
メソッドを使用すると、マテリアライズド・ビューを自動的にリフレッシュできます。したがって、マテリアライズド・ビューが定義されている表の更新トランザクションがコミットされるたびに、その変更内容がマテリアライズド・ビューに自動的に反映されます。このアプローチを使用するメリットは、マテリアライズド・ビューのリフレッシュに注意する必要がないことです。唯一のデメリットは、余分な処理が必要なため、コミット完了までの所要時間が少し長くなることです。ただし、データ・ウェアハウスでは、同時プロセスで同じ表の更新が試みられることはまずないため、これは問題ではありません。
7.1.7 マテリアライズド・ビューのON STATEMENTリフレッシュについて
ON STATEMENT
リフレッシュ・モードを使用するマテリアライズド・ビューは、マテリアライズド・ビューの実表のいずれかに対してDML操作が実行されるたびに自動的にリフレッシュされます。
ON STATEMENT
リフレッシュ・モードを使用すると、実表が変更された場合、マテリアライズド・ビューにすぐに反映されます。トランザクションをコミットしたり、マテリアライズド・ビュー・ログを実表に保持する必要はありません。DML文が後でロールバックされた場合、マテリアライズド・ビューに加えられた対応する変更もロールバックされます。
ON STATEMENT
リフレッシュ・モードを使用するには、マテリアライズド・ビューが高速リフレッシュ可能である必要があります。高速リフレッシュのパフォーマンスを向上させるために、ファクト表のROWID
列に索引が自動的に作成されます。
ON STATEMENT
リフレッシュ・モードの利点は、マテリアライズド・ビュー・ログを保持するというオーバーヘッドを伴うことなく、マテリアライズド・ビューが実表内のデータと常に同期される点です。ただし、このモードでは、DML操作の一環としてマテリアライズド・ビューがリフレッシュされるため、DML操作の実行に要する時間が長くなることがあります。
関連項目:
ON STATEMENT
句の制限については、『Oracle Database SQL言語リファレンス』を参照してください
例7-1 ON STATEMENTリフレッシュを使用するマテリアライズド・ビューの作成
この例では、ON STATEMENT
リフレッシュ・モードを使用し、sh.sales
、sh.customers
およびsh.products
の各表に基づくマテリアライズド・ビューsales_mv_onstat
を作成します。実表のいずれかに対してDML操作が実行されると、マテリアライズド・ビューは自動的にリフレッシュされます。マテリアライズド・ビューをリフレッシュするために、DML操作の後にコミットは必要ありません。
CREATE MATERIALIZED VIEW sales_mv_onstat
REFRESH FAST ON STATEMENT USING TRUSTED CONSTRAINT
AS
SELECT s.rowid sales_rid, c.cust_first_name first_name, c.cust_last_name last_name,
p.prod_name prod_name,
s.quantity_sold quantity_sold, s.amount_sold amount_sold
FROM sh.sales s, sh.customers c, sh.products p
WHERE s.cust_id = c.cust_id and s.prod_id = p.prod_id;
7.1.8 DBMS_MVIEWパッケージによる手動リフレッシュについて
マテリアライズド・ビューをON
DEMAND
でリフレッシュする場合は、次の表で示す、4つのリフレッシュ方法のうち1つを指定できます。デフォルト・オプションは、マテリアライズド・ビューの作成時に定義できます。表7-1にリフレッシュ・オプションを示します。
表7-1 ON DEMANDリフレッシュ方法
リフレッシュ・オプション | パラメータ | 説明 |
---|---|---|
|
|
マテリアライズド・ビューの定義問合せを再計算することでリフレッシュします。 |
|
|
マテリアライズド・ビューへの変更を増分的に適用することでリフレッシュします。 ローカル・マテリアライズド・ビューの場合は、オプティマイザが最も効率的と判断したリフレッシュ方法が選択されます。考えられるリフレッシュ方法は、ログベースの |
|
|
ディテール表内の変更された物理パーティションの影響を受ける、マテリアライズド・ビュー内の行を再計算することでリフレッシュします。 |
LPCT |
L |
ディテール表内の変更された論理パーティションの影響を受ける、マテリアライズド・ビュー内の行を再計算することでリフレッシュします。 |
|
|
高速リフレッシュを試みます。それができない場合は、完全リフレッシュを行います。 ローカル・マテリアライズド・ビューの場合は、オプティマイザが最も効率的と判断したリフレッシュ方法が選択されます。考えられるリフレッシュ方法は、ログベースの |
ON DEMAND
リフレッシュを実行するために、DBMS_MVIEW
パッケージの3つのリフレッシュ・プロシージャを使用できます。それぞれに、一連の固有のパラメータがあります。
関連項目:
DBMS_MVIEW
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
7.1.9 REFRESHを使用した特定のマテリアライズド・ビューのリフレッシュ
DBMS_MVIEW.REFRESH
プロシージャを使用して、1つ以上のマテリアライズド・ビューをリフレッシュできます。一部のパラメータはレプリケーションにのみ使用されるため、ここでは説明しません。このプロシージャを使用するために必要なパラメータは次のとおりです。
-
カンマで区切られた、リフレッシュ対象のマテリアライズド・ビューのリスト
-
リフレッシュ方法:
F
-Fast、P
-Fast_PCT、L-FAST_LPCT、?
-Force、C
-Complete -
使用するロールバック・セグメント
-
エラー発生後のリフレッシュ(
TRUE
またはFALSE
)ブール・パラメータ。
TRUE
に設定すると、number_of_failures
出力パラメータは失敗したリフレッシュの数に設定され、通常のエラー・メッセージによって失敗の発生が示されます。インスタンスに関するアラート・ログに、リフレッシュ・エラーの詳細が示されます。デフォルト値のFALSE
に設定すると、最初にエラーが発生したときにリフレッシュが停止し、リスト内の残りのマテリアライズド・ビューはリフレッシュされません。 -
次の4つのパラメータは、レプリケーション・プロセスで使用されます。ウェアハウスのリフレッシュの場合は、
FALSE, 0,0,0
に設定してください。 -
アトミック・リフレッシュ(
TRUE
またはFALSE
)TRUE
に設定すると、すべてのリフレッシュが1トランザクションで行われます。FALSE
に設定されると、各マテリアライズド・ビューは別々のトランザクションで非アトミックにリフレッシュされます。FALSE
に設定すると、パラレルDMLによってリフレッシュが最適化され、マテリアライズド・ビューのDDLが切り捨てられます。マテリアライズド・ビューをアトミック・モードでリフレッシュする際、リライト整合性モードがstale_tolerated
に設定されている場合にクエリー・リライトを使用できます。リフレッシュがネステッド・ビューで実行される場合は、アトミック・リフレッシュは保証されません。 -
ホーム外リフレッシュを使用するかどうか
このパラメータは、既存のすべてのリフレッシュ方法(
F
、P
、C
、?
)とともに使用できます。したがって、F
とout_of_place
=
true
を指定すると、ホーム外高速リフレッシュが試みられます。同様に、P
とout_of_place
=
true
を指定すると、ホーム外PCTリフレッシュが試みられます。
たとえば、マテリアライズド・ビューcal_month_sales_mv
に高速リフレッシュを行うには、DBMS_MVIEW
パッケージを次のようにコールします。
DBMS_MVIEW.REFRESH('CAL_MONTH_SALES_MV', 'F', '', TRUE, FALSE, 0,0,0, FALSE, FALSE);
複数のマテリアライズド・ビューを同時にリフレッシュすることが可能です。また、その際、すべてに同じリフレッシュ方法を使用する必要はありません。それぞれに異なるリフレッシュ方法を適用するには、マテリアライズド・ビューのリスト順に複数のメソッド・コードを指定します(カンマなし)。たとえば、次のように指定すると、cal_month_sales_mv
は完全リフレッシュされ、fweek_pscat_sales_mv
は高速リフレッシュされます。
DBMS_MVIEW.REFRESH('CAL_MONTH_SALES_MV, FWEEK_PSCAT_SALES_MV', 'CF', '', TRUE, FALSE, 0,0,0, FALSE, FALSE);
リフレッシュ方法を指定しなければ、マテリアライズド・ビューの定義で指定したデフォルトのリフレッシュ方法が使用されます。
7.1.10 REFRESH_ALL_MVIEWSを使用したすべてのマテリアライズド・ビューのリフレッシュ
リフレッシュするマテリアライズド・ビューを指定する場合、プロシージャDBMS_MVIEW.REFRESH_ALL_MVIEWS
を使用する方法もあります。このプロシージャでは、すべてのマテリアライズド・ビューがリフレッシュされます。リフレッシュに失敗したマテリアライズド・ビューがあると、その数がレポートされます。
このプロシージャのパラメータは次のとおりです。
-
失敗数(
OUT
変数) -
リフレッシュ方法:
F
-Fast、P
-Fast_PCT、L-FAST_LPCT、?
-Force、C
-Complete -
エラー発生後のリフレッシュ(
TRUE
またはFALSE
)ブール・パラメータ。
TRUE
に設定すると、number_of_failures
出力パラメータは失敗したリフレッシュの数に設定され、通常のエラー・メッセージによって失敗の発生が示されます。インスタンスに関するアラート・ログに、リフレッシュ・エラーの詳細が示されます。デフォルト値のFALSE
に設定すると、最初にエラーが発生したときにリフレッシュが停止し、リスト内の残りのマテリアライズド・ビューはリフレッシュされません。 -
アトミック・リフレッシュ(
TRUE
またはFALSE
)TRUE
に設定すると、すべてのリフレッシュが1トランザクションで行われます。FALSE
に設定されると、各マテリアライズド・ビューは別々のトランザクションで非アトミックにリフレッシュされます。FALSE
に設定すると、パラレルDMLによってリフレッシュが最適化され、マテリアライズド・ビューのDDLが切り捨てられます。マテリアライズド・ビューをアトミック・モードでリフレッシュする際、リライト整合性モードがstale_tolerated
に設定されている場合にクエリー・リライトを使用できます。リフレッシュがネステッド・ビューで実行される場合は、アトミック・リフレッシュは保証されません。 -
ホーム外リフレッシュを使用するかどうか
このパラメータは、既存のすべてのリフレッシュ方法(
F
、P
、C
、?
)とともに使用できます。したがって、F
とout_of_place
=
true
を指定すると、ホーム外高速リフレッシュが試みられます。同様に、P
とout_of_place
=
true
を指定すると、ホーム外PCTリフレッシュが試みられます。
次に、すべてのマテリアライズド・ビューをリフレッシュする例を示します。
DBMS_MVIEW.REFRESH_ALL_MVIEWS(failures,'C','', TRUE, FALSE, FALSE);
7.1.11 REFRESH_DEPENDENTを使用した依存マテリアライズド・ビューのリフレッシュ
3番目のプロシージャDBMS_MVIEW.REFRESH_DEPENDENT
では、特定の表または表のリストに依存するマテリアライズド・ビューのみがリフレッシュされます。たとえば、変更がorders
表には反映されるが、customer payments
表には反映されないとします。orders
表を参照するマテリアライズド・ビューのみをリフレッシュするには、REFRESH_DEPENDENTプロシージャをコールします。
このプロシージャのパラメータは次のとおりです。
-
失敗数(
OUT
変数) -
依存する表
-
リフレッシュ方法:
F
-Fast、P
-Fast_PCT、L-FAST_LPCT、?
-Force、C
-Complete -
使用するロールバック・セグメント
-
エラー発生後のリフレッシュ(
TRUE
またはFALSE
)ブール・パラメータ。
TRUE
に設定すると、number_of_failures
出力パラメータは失敗したリフレッシュの数に設定され、通常のエラー・メッセージによって失敗の発生が示されます。インスタンスに関するアラート・ログに、リフレッシュ・エラーの詳細が示されます。デフォルト値のFALSE
に設定すると、最初にエラーが発生したときにリフレッシュが停止し、リスト内の残りのマテリアライズド・ビューはリフレッシュされません。 -
アトミック・リフレッシュ(
TRUE
またはFALSE
)TRUE
に設定すると、すべてのリフレッシュが1トランザクションで行われます。FALSE
に設定されると、各マテリアライズド・ビューは別々のトランザクションで非アトミックにリフレッシュされます。FALSE
に設定すると、パラレルDMLによってリフレッシュが最適化され、マテリアライズド・ビューのDDLが切り捨てられます。マテリアライズド・ビューをアトミック・モードでリフレッシュする際、リライト整合性モードがstale_tolerated
に設定されている場合にクエリー・リライトを使用できます。リフレッシュがネステッド・ビューで実行される場合は、アトミック・リフレッシュは保証されません。 -
ネストされているかどうか
TRUE
に設定すると、依存順序に基づいて指定した表のセットのすべての依存マテリアライズド・ビューがリフレッシュされ、マテリアライズド・ビューが実表に対して最新の状態になります。 -
ホーム外リフレッシュを使用するかどうか
このパラメータは、既存のすべてのリフレッシュ方法(
F
、P
、C
、?
)とともに使用できます。したがって、F
とout_of_place
=
true
を指定すると、ホーム外高速リフレッシュが試みられます。同様に、P
とout_of_place
=
true
を指定すると、ホーム外PCTリフレッシュが試みられます。
customers
表を参照するすべてのマテリアライズド・ビューの完全リフレッシュを実行するには、次のように指定します。
DBMS_MVIEW.REFRESH_DEPENDENT(failures, 'CUSTOMERS', 'C', '', FALSE, FALSE, FALSE);
7.1.12 リフレッシュへのジョブ・キューの使用について
ジョブ・キューを使用して、複数のマテリアライズド・ビューをパラレルにリフレッシュできます。キューが使用できない場合、高速リフレッシュでは各ビューがフォアグラウンド・プロセスで順次リフレッシュされます。キューを使用可能にするには、JOB_QUEUE_PROCESSES
パラメータを設定する必要があります。このパラメータでバックグラウンド・ジョブ・キュー・プロセスの数を定義することにより、同時に実行可能なマテリアライズド・ビューの数が決まります。同時リフレッシュの数と各リフレッシュの並列度のバランスが調整されます。マテリアライズド・ビューがリフレッシュされる順序は、ネステッド・マテリアライズド・ビューで指定されている依存性、および他のマテリアライズド・ビューに対するクエリー・リライトによる効率的なリフレッシュの可能性によって決まります(詳細は、マテリアライズド・ビューのリフレッシュのスケジューリングを参照)。このパラメータが有効なのは、atomic_refresh
がFALSE
に設定されている場合のみです。
DBMS_MVIEW.REFRESH
を実行中のプロセスに割込みが入るか、そのインスタンスが停止すると、ジョブ・キュー・プロセスで実行中だったリフレッシュ・ジョブが再度キューに入れられ、引き続き実行されます。これらのジョブを削除するには、DBMS_JOB.REMOVE
プロシージャを使用します。
関連項目:
-
DBMS_JOB
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
7.1.13 高速リフレッシュが可能なパターン
すべてのマテリアライズド・ビューの高速リフレッシュが可能であるとは限りません。したがって、パッケージDBMS_MVIEW.EXPLAIN_MVIEW
を使用して、マテリアライズド・ビューに使用可能なリフレッシュ方法を判断します。
マテリアライズド・ビューを高速リフレッシュできるようにする方法がわからない場合は、DBMS_ADVISOR.TUNE_MVIEW
プロシージャを使用して、高速リフレッシュできるマテリアライズド・ビューの作成に必要な文を含むスクリプトを指定します。
関連項目:
-
DBMS_MVIEW
パッケージの詳細は、基本的なマテリアライズド・ビューを参照してください。
7.1.14 近似問合せに基づいたマテリアライズド・ビューのリフレッシュ
Oracle Databaseは、近似問合せを使用して定義されているマテリアライズド・ビューの高速リフレッシュを実行します。
近似問合せには、近似結果を返すSQL関数が含まれます。近似問合せを含むマテリアライズド・ビューのリフレッシュは、マテリアライズド・ビューの実表で実行されるDML操作によって異なります。
-
挿入操作の場合は、詳細パーセンタイルを含むマテリアライズド・ビューに対して高速リフレッシュが使用されます。
-
削除操作または削除につながるDML操作(
UPDATE
やMERGE
など)の場合は、マテリアライズド・ビューにWHERE
句が含まれない場合のみ、近似集計を含むマテリアライズド・ビューに対して高速リフレッシュが使用されます。
例7-2 近似問合せに基づいたマテリアライズド・ビューのリフレッシュ
次の例では、近似問合せに基づいたマテリアライズド・ビューpercentile_per_pdt
の高速リフレッシュを実行します。
exec DBMS_MVIEW.REFRESH('percentile_per_pdt', method => 'F');
7.1.15 コミット時のマテリアライズド・ビューの同時リフレッシュについて
Oracle Database 23ai以降では、コミット時の複数のマテリアライズド・ビューを同時にリフレッシュできます。
マテリアライズド・ビューの同時リフレッシュは、複数のセッションで同一のコミット時のアトミック・マテリアライズド・ビューを同時にリフレッシュできることを意味します。
同時リフレッシュが有効になっている場合、実表に対してDMLを実行する複数のセッションで、マテリアライズド・ビューを同時にリフレッシュできます。同時セッションの数に制限はありません。
同時リフレッシュが無効になっている場合、マテリアライズド・ビューのリフレッシュはシリアライズされます。この場合、複数のセッションでマテリアライズド・ビューを同時にリフレッシュすることはできません。マテリアライズド・ビューを更新できるのは、一度に1つのリフレッシュ・セッションのみです。現在のセッションが完了するまで、その他のリフレッシュはブロックされます。その後、次のセッションを続行できます。
コミット時のマテリアライズド・ビューの同時リフレッシュに最適なユース・ケース
この機能は、OLTPでコミット時のマテリアライズド・ビューのリフレッシュを実行する場合や、多数の同時DMLトランザクションによってファクト表のみが更新される場合に便利です。
コミット時のマテリアライズド・ビューの同時リフレッシュの有効化
CREATE MATERIALIZED VIEW
またはALTER MATERIALIZED VIEW
文で同時リフレッシュを有効または無効にできます。{ ENABLE | DISABLE } CONCURRENT REFRESH
次に例を示します。
CREATE MATERIALIZED VIEW "T1"."MV1" ("C1", "C2")
SEGMENT CREATION DEFERRED
REFRESH FAST ON COMMIT
WITH PRIMARY KEY USING DEFAULT LOCAL ROLLBACK SEGMENT
USING ENFORCED CONSTRAINTS DISABLE ON QUERY COMPUTATION DISABLE QUERY REWRITE
ENABLE CONCURRENT REFRESH
AS SELECT "TB1"."C1" "C1","TB1"."C2" "C2" FROM "TB1" "TB1
コミット時のマテリアライズド・ビューの同時リフレッシュが許可される条件
- 同時リフレッシュが有効になっている。(有効にできるのは、コミット時のマテリアライズド・ビューのリフレッシュのみです。)
- すべての同時DMLセッションで同じ実表が更新される。
- 異なるリフレッシュ・セッションで更新されたマテリアライズド・ビュー行が重複しない。
制限事項
マテリアライズド・ビューDDLのコミット時の高速リフレッシュでは、同時リフレッシュを有効にできません。同時リフレッシュを有効にできるのは、コミット時のマテリアライズド・ビューのみです。
コミット時のマテリアライズド・ビューの同時リフレッシュが有効かどうかを判断する方法
ビューALL_MVIEWSをチェックして、同時リフレッシュが有効かどうかなど、マテリアライズド・ビューのすべてのプロパティを表示できます。
関連項目:
Oracle Database SQL言語リファレンスのCREATE MATERIALIZED VIEW文の説明では、{ ENABLE | DISABLE } CONCURRENT REFRESHの完全なコンテキストが示されています。DBMS_MVIEW_REFRESHおよびデータベースPL/SQLパッケージおよびタイプ・リファレンスのマテリアライズド・ビューのリフレッシュに関連するその他のAPIを参照してください。
7.1.16 表のオンライン再定義中に依存マテリアライズド・ビューをリフレッシュする方法について
DBMS_REDEFINITION
パッケージを使用して表のオンライン再定義を実行しているときに、再定義されている表に依存する高速リフレッシュ可能なマテリアライズド・ビューの増分リフレッシュを実行できます。
Oracle Database 12cリリース2 (12.2)より前は、再定義が実行されている表の依存マテリアライズド・ビューをリフレッシュするには、再定義処理が完了した後に完全なリフレッシュを手動で実行する必要がありました。
表のオンライン再定義中に、依存マテリアライズド・ビューを増分リフレッシュするには、DBMS_REDEFINITON.REDEF_TABLE
プロシージャのrefresh_dep_mviews
パラメータにYを設定します。表のオンライン再定義中に依存マテリアライズド・ビューをリフレッシュできるのは、マテリアライズド・ビューが高速リフレッシュ可能で、ROWID
ベースのマテリアライズド・ビューまたはマテリアライズド結合ビューではない場合のみです。これらの制限に従っていないマテリアライズド・ビューはリフレッシュされません。
次の依存マテリアライズド・ビューを持つmy_sales
表について考えてみます。
-
my_sales_pk_mv
: 高速リフレッシュ可能で主キーベースのマテリアライズド・ビュー -
my_sales_rid_mv
: 高速リフレッシュ可能でROWID
ベースのマテリアライズド・ビュー -
my_sales_mjv
: 高速リフレッシュ可能なマテリアライズド結合ビュー -
my_sales_mav
: 高速リフレッシュ可能なマテリアライズド集計ビュー -
my_sales_rmv
: 完全リフレッシュのみが可能なマテリアライズド・ビュー
次のコマンドを実行した場合、高速リフレッシュはmy_sales_pk_mv
およびmy_sales_mav
マテリアライズド・ビューでのみ実行されます。
DBMS_REDEFINITION.REDEF_TABLE(
uname => 'SH',
tname => 'MY_SALES',
table_compression_type => 'ROW STORE COMPRESS ADVANCED',
refresh_dep_mviews => 'Y');
関連項目:
7.1.17 パラレル化の推奨初期化パラメータ
パラレル化を効果的にするには、次の初期化パラメータを正しく設定する必要があります。
-
PARALLEL_MAX_SERVERS
は、パラレル化に対応できるように十分高い値にします。リフレッシュ文に必要な子プロセスの数を考慮する必要があります。たとえば、並列度が8であれば、16個の子プロセスが必要です。 -
インスタンスでソートと結合のメモリー使用を自動的に管理するには、
PGA_AGGREGATE_TARGET
を設定する必要があります。メモリー・パラメータを手動で設定する場合は、SORT_AREA_SIZE
をHASH_AREA_SIZE
未満にする必要があります。 -
OPTIMIZER_MODE
は、all_rows
と同じ値にします。
すべての表および索引を効率的に分析すると、最適化が向上します。
7.1.19 マテリアライズド・ビューのステータスのチェック
これらは、表のパーティションの状態を確認し、マテリアライズド・ビューのデータの最新または失効の範囲を判別できるビューです。
-
*_MVIEWS
マテリアライズド・ビューのパーティション・チェンジ・トラッキング(PCT)情報の判別に使用します。
-
*_MVIEW_DETAIL_RELATIONS
マテリアライズド・ビューの基になるディテール表のパーティション情報を表示するのに使用します。
-
*_MVIEW_DETAIL_PARTITION
最新のパーティションを判別するのに使用します。(物理パーティションのみ。)
-
*_MVIEW_DETAIL_SUBPARTITION
最新のサブパーティションを判別するのに使用します。(物理パーティションのみ。)
*_MVIEW_DETAIL_LOGICAL_PARTITIONS
マテリアライズド・ビューの論理パーティション・チェンジ・トラッキング(LPCT)情報の判別に使用します。
物理パーティションが最新であるかどうか確認
パーティション・チェンジ・トラッキング(PCT)を使用して、物理パーティションが最新であるかどうかを確認できます。失効したパーティションがあるインスタンスを次に示します。

パーティションのPCTの最新状態の情報にアクセスするには、次のようにUSER_MVIEW_DETAIL_PARTITION
を問い合せます。
SELECT MVIEW_NAME,DETAILOBJ_NAME,DETAIL_PARTITION_NAME, DETAIL_PARTITION_POSITION,FRESHNESS FROM USER_MVIEW_DETAIL_PARTITION WHERE MVIEW_NAME = MV1;
MVIEW_NAME DETAILOBJ_NAME DETAIL_PARTITION_NAME DETAIL_PARTITION_POSITION FRESHNESS ---------- -------------- --------------------- ------------------------- --------- MV1 T1 P1 1 FRESH MV1 T1 P2 2 FRESH MV1 T1 P3 3 STALE MV1 T1 P4 4 FRESH
論理パーティションが最新であるかどうか確認
論理パーティション・チェンジ・トラッキング(LPCT)を使用して、論理パーティションの失効/最新状態を判断します。
この例では、論理パーティションはLP1、LP2、LP3およびLP4です。LP3が失効していると仮定します。

ノート:
論理パーティション化では、サブパーティションはサポートされていません。DBA_MVIEW_DETAIL_LOGICAL_PARTITION
を問い合せて、論理パーティションが最新であるかどうか判断できます。
SQL> SELECT MVIEW_NAME, DETAILOBJ_NAME, LPARTNAME, LPART#, FRESHNESS \
FROM DBA_MVIEW_DETAIL_LOGICAL_PARTITION WHERE MVIEW_NAME = 'MV1' ORDER BY 1,2,3,4;
MVIEW_NAME DETAILOBJ_NAME LPARTNAME LPART# FRESHNESS
----------------------------------–-------------------------------------------
MV1 SALES LP1 1 FRESH
MV1 SALES LP2 2 FRESH
MV1 SALES LP3 3 STALE
MV1 SALES LP4 4 FRESH
関連項目:
詳細および例は、最新状態の判別に使用するビューの使用例を参照してください。
7.1.19.1 最新状態の判別に使用するビューの使用例
次に、マテリアライズド・ビューおよびそのディテール表のパーティション最新状態の情報の表示方法を示す例を示します。
例7-3 マテリアライズド・ビューのPCTステータスの確認
マテリアライズド・ビューのPCT情報にアクセスするには、次のようにUSER_MVIEWS
を問い合せます。
SELECT MVIEW_NAME, NUM_PCT_TABLES, NUM_FRESH_PCT_REGIONS, NUM_STALE_PCT_REGIONS FROM USER_MVIEWS WHERE MVIEW_NAME = MV1; MVIEW_NAME NUM_PCT_TABLES NUM_FRESH_PCT_REGIONS NUM_STALE_PCT_REGIONS ---------- -------------- --------------------- --------------------- MV1 1 9 3
例7-4 マテリアライズド・ビューのディテール表におけるPCTステータスの確認
PCTディテール表の情報にアクセスするには、次のようにUSER_MVIEW_DETAIL_RELATIONS
を問い合せます。
SELECT MVIEW_NAME, DETAILOBJ_NAME, DETAILOBJ_PCT, NUM_FRESH_PCT_PARTITIONS, NUM_STALE_PCT_PARTITIONS FROM USER_MVIEW_DETAIL_RELATIONS WHERE MVIEW_NAME = MV1;
MVIEW_NAME DETAILOBJ_NAME DETAIL_OBJ_PCT NUM_FRESH_PCT_PARTITIONS NUM_STALE_PCT_PARTITIONS ---------- -------------- -------------- ------------------------ ------------------------ MV1 T1 Y 3 1
例7-5 最新のサブパーティションの確認
サブパーティションのPCTの最新状態の情報にアクセスするには、次のようにUSER_MVIEW_DETAIL_SUBPARTITION
を問い合せます。
SELECT MVIEW_NAME,DETAILOBJ_NAME,DETAIL_PARTITION_NAME, DETAIL_SUBPARTITION_NAME, DETAIL_SUBPARTITION_POSITION,FRESHNESS FROM USER_MVIEW_DETAIL_SUBPARTITION WHERE MVIEW_NAME = MV1;
MVIEW_NAME DETAILOBJ DETAIL_PARTITION DETAIL_SUBPARTITION_NAME DETAIL_SUBPARTITION_POS FRESHNESS ---------- --------- ---------------- ------------------------ ----------------------- --------- MV1 T1 P1 SP1 1 FRESH MV1 T1 P1 SP2 1 FRESH MV1 T1 P1 SP3 1 FRESH MV1 T1 P2 SP1 1 FRESH MV1 T1 P2 SP2 1 FRESH MV1 T1 P2 SP3 1 FRESH MV1 T1 P3 SP1 1 STALE MV1 T1 P3 SP2 1 STALE MV1 T1 P3 SP3 1 STALE MV1 T1 P4 SP1 1 FRESH MV1 T1 P4 SP2 1 FRESH MV1 T1 P4 SP3 1 FRESH
7.1.20 マテリアライズド・ビューのリフレッシュのスケジュール
ほとんどの場合、データベースには複数のマテリアライズド・ビューがあります。一部のマテリアライズド・ビューは、他のマテリアライズド・ビューに対してリライトして計算されているものもあります。これは、ネステッド・マテリアライズド・ビューがある、または一部の階層の異なるレベルにマテリアライズド・ビューがあるデータ・ウェアハウス環境では、非常に一般的なことです。
このような場合、BUILD DEFERRED
としてマテリアライズド・ビューを作成し、DBMS_MVIEW
パッケージのいずれかのリフレッシュ・プロシージャを発行してすべてのマテリアライズド・ビューをリフレッシュする必要があります。Oracle Databaseによって、依存性が計算され、正しい順序でマテリアライズド・ビューがリフレッシュされます。階層的キューブのマテリアライズド・ビューの例で説明されている完全な階層的キューブの例を参照してください。すべてのマテリアライズド・ビューがBUILD DEFERRED
として作成されているとします。マテリアライズド・ビューをBUILD DEFERRED
として作成すると、すべてのマテリアライズド・ビューのメタデータのみが作成されます。これで、DBMS_MVIEW
パッケージのリフレッシュ・プロシージャのいずれかをコールし、すべてのマテリアライズド・ビューを正しい順序でリフレッシュできます。
DECLARE numerrs PLS_INTEGER; BEGIN DBMS_MVIEW.REFRESH_DEPENDENT ( number_of_failures => numerrs, list=>'SALES', method => 'C'); DBMS_OUTPUT.PUT_LINE('There were ' || numerrs || ' errors during refresh'); END; /
プロシージャは、マテリアライズド・ビューを依存性の順序(sales_hierarchical_mon_cube_mv
から始まり、sales_hierarchical_qtr_cube_mv
、sales_hierarchical_yr_cube_mv
、sales_hierarchical_all_cube_mv
という順序)でリフレッシュします。各マテリアライズド・ビューは、リストにおける1つ前のマテリアライズド・ビューに対してリライトされます。
同じ種類のリライトは、PCTリフレッシュを行う際にも使用できます。PCTリフレッシュでは、ディテール表で変更された行に対応するマテリアライズド・ビューの行が再計算されます。リフレッシュ時に最新のマテリアライズド・ビューが他にある場合は、ディテール表ではなくそのマテリアライズド・ビューが直接使用されます。
したがって、指定した方法に関係なく、マテリアライズド・ビューのリストをDBMS_MVIEW
パッケージのいずれかのリフレッシュ・プロシージャに渡すことは有益です。これによって、プロシージャは、マテリアライズド・ビューに対してリフレッシュを実行する順序を認識できます。
7.2 マテリアライズド・ビューのリフレッシュのヒント
この項の内容は次のとおりで、マテリアライズド・ビューのリフレッシュのヒントを含みます。
7.2.1 集計を含むマテリアライズド・ビューのリフレッシュのヒント
ここでは、集計を含むマテリアライズド・ビューのリフレッシュ機能を使用する場合のガイドラインを示します。
-
高速リフレッシュの場合は、
ROWID
、SEQUENCE
およびINCLUDING
NEW
VALUES
句を使用して、マテリアライズド・ビューに関連するすべてのディテール表のマテリアライズド・ビュー・ログを作成します。マテリアライズド・ビュー・ログには、マテリアライズド・ビューに使用されると思われる表の列をすべて含めます。
高速リフレッシュは、マテリアライズド・ビュー・ログで
SEQUENCE
オプションが省略されていても可能な場合があります。すべてのディテール表で挿入または削除しか発生しないと判断できる場合、マテリアライズド・ビュー・ログにはSEQUENCE
句は不要です。ただし、複数の表が更新される可能性があるか必要な場合、または特定の更新の手順が不明な場合は、SEQUENCE
句が含まれているかどうかを確認してください。 -
Oracleのバルク・ロード・ユーティリティまたはダイレクト・パス・インサート
(ロードに対する
APPEND
ヒント付きのINSERT
)を使用します。Oracle Database 12cより、データベースではバルク・ロード操作の一部として(CTASおよびIAS)、索引の作成時の統計の収集方法に似た表統計の自動収集を行います。データ・ロードの際に統計を収集することによって、スキャン操作の追加を回避し、ユーザーがデータを使用できるようになるとすぐに必要な統計を提供できます。これは、従来の挿入に比べてはるかに効率的です。ロード中はすべての制約を使用禁止にし、ロード終了後に使用可能に戻します。ダイレクト・ロードと従来型DMLのどちらを使用する場合も、マテリアライズド・ビュー・ログは必要であるため注意してください。
マテリアライズド・ビューに対する従来型の複合DML操作、ダイレクト・パス・インサート
および高速リフレッシュの順序を最適化してください。従来のDMLおよびダイレクト・ロードと混在させて高速リフレッシュを使用できます。高速リフレッシュでは、次に示すように、ダイレクト・ロードのみが発生することがわかっていれば、大幅な最適化を実行できます。
-
ディテール表へのダイレクト・パス・インサート
(SQL*Loaderまたは
INSERT /*+ APPEND */
)を行います。 -
マテリアライズド・ビューのリフレッシュ
-
従来型の複合DML操作を行います。
-
マテリアライズド・ビューをリフレッシュします。
高速リフレッシュを、ディテール表に対する従来型の複合DML(
INSERT
、UPDATE
およびDELETE
)と併用できます。ただし、高速リフレッシュで処理中に大幅な最適化を実行できるのは、次のように、表に対して挿入または削除のみが行われていることが検出される場合です。-
ディテール表に対するDML
INSERT
またはDELETE
-
複数のマテリアライズド・ビューのリフレッシュ
-
ディテール表のDML更新
-
マテリアライズド・ビューをリフレッシュします。
さらに最適化するには、
INSERT
とDELETE
を分離します。可能であれば、最後にリフレッシュを1つのみ発行するのではなく、前述のように各種のデータ変更の後にリフレッシュを実行します。可能でない場合は、従来のDMLを挿入対象の表に限定すると、リフレッシュのパフォーマンスが大幅に改善されます。DELETEとダイレクト・ロードの混在を回避してください。
さらに、
ON
COMMIT
リフレッシュの場合、Oracleは、コミットされたトランザクションで実行されたDMLのタイプを記録します。したがって、同じトランザクションの他の表には、ダイレクト・パス・インサートおよびDMLを実行しないでください。Oracleがリフレッシュ・フェーズを最適化できない可能性があります。
ON
COMMIT
マテリアライズド・ビューの場合は、各トランザクションの最後にリフレッシュが自動的に発生します。DML文を分離できない場合があり、その場合はトランザクションを短くすると有効です。ただし、ディテール表に対して多数の変更を行う場合は、更新のたびにリフレッシュするより、それらの更新を1回のトランザクションで実行し、コミット時に一度にマテリアライズド・ビューをリフレッシュする方が効率的です。 -
-
次の方法を使用できるため、表をパーティション化することをお薦めします。
-
パラレルDML
大量のロードまたはリフレッシュの場合は、パラレルDMLを使用可能にすると、処理時間を短縮できます。
-
パーティション・チェンジ・トラッキング(PCT)高速リフレッシュ
マテリアライズド・ビューの高速リフレッシュは、ディテール表に対するパーティション・メンテナンス操作後に実行できます。マテリアライズド・ビューでPCTを使用可能にする方法の詳細は、パーティション・チェンジ・トラッキングについてを参照してください。
-
-
また、マテリアライズド・ビューをパーティション化すると、リフレッシュでパラレルDMLを使用してマテリアライズド・ビューを更新できるため、パフォーマンスが改善されます。たとえば、ディテール表とマテリアライズド・ビューがパーティション化されており、PARALLEL句があるとします。次の順序により、Oracleではマテリアライズド・ビューのリフレッシュをパラレル化できます。
-
ディテール表にバルク・ロードします。
-
ALTER
SESSION
ENABLE
PARALLEL
DML
文でパラレルDMLを使用可能にします。 -
マテリアライズド・ビューをリフレッシュします。
-
-
DBMS_MVIEW.REFRESH
を使用してリフレッシュを行うには、パラメータatomic_refresh
をFALSE
に設定します。-
COMPLETE
リフレッシュでは、これにより、マテリアライズド・ビューの既存の行がTRUNCATE
によって削除されます。これはDELETEより高速です。 -
PCT
リフレッシュでは、マテリアライズド・ビューが適切にパーティション化されている場合は、これにより、マテリアライズド・ビューの影響を受けるパーティションの行がTRUNCATE
PARTITION
によって削除されます。これはDELETEより高速です。 -
FAST
またはFORCE
リフレッシュでは、COMPLETE
リフレッシュまたはPCTリフレッシュが選択された場合、これにより、前述のTRUNCATE
最適化を使用できます。
-
-
JOB_QUEUES
を指定してDBMS_MVIEW.REFRESH
を使用する場合は、atomic
をFALSE
に設定してください。このように設定しなければ、JOB_QUEUES
は使用されません。ジョブ・キュー・プロセスの数を、プロセッサ数より大きくなるように設定します。ジョブ・キューが使用可能になっており、リフレッシュするマテリアライズド・ビューが多い場合は、個別にコールするより1つのコマンドですべてをリフレッシュするほうが高速です。
-
リフレッシュしたマテリアライズド・ビューをクエリー・リライトで使用できるようにするには、
REFRESH
FORCE
を使用します。最適なリフレッシュ方法が選択されます。高速リフレッシュができない場合は、完全リフレッシュが行われます。 -
1回のプロシージャ・コールで、すべてのマテリアライズド・ビューをリフレッシュします。これにより、ネステッド・マテリアライズド・ビューで指定された依存性、および他のマテリアライズド・ビューに対するクエリー・リライトを使用した効率的なリフレッシュを考慮した正しい順序によるすべてのマテリアライズド・ビューのリフレッシュが、Oracleによってスケジューリングされます。
7.2.2 集計を含まないマテリアライズド・ビューのリフレッシュのヒント
結合を含み、集計を含まないマテリアライズド・ビューは、集計を含むマテリアライズド・ビューよりもかなりサイズが大きくなる傾向があるため、ディテール表の結合列ROWIDのそれぞれに索引を設定すると、リフレッシュ・パフォーマンスが大幅に向上します。たとえば、次のマテリアライズド・ビューを考えてみます。
CREATE MATERIALIZED VIEW detail_fact_mv BUILD IMMEDIATE AS SELECT s.rowid "sales_rid", t.rowid "times_rid", c.rowid "cust_rid", c.cust_state_province, t.week_ending_day, s.amount_sold FROM sales s, times t, customers c WHERE s.time_id = t.time_id AND s.cust_id = c.cust_id;
この場合は、sales_rid
、times_rid
およびcust_rid
列に索引を作成します。リフレッシュを起動する前に、セッションでのパラレルDMLを可能にするとともにパーティション化も行ってください。リフレッシュ・パフォーマンスが大幅に向上します。
このタイプのマテリアライズド・ビューは、DMLがディテール表に実行される場合でも高速リフレッシュも可能です。このタイプのマテリアライズド・ビューでも、単一表集計マテリアライズド・ビューと同じ手順に従ってください。つまり、1つのタイプの変更(ダイレクト・パス・インサートまたはDML)を行うたびにマテリアライズド・ビューをリフレッシュします。これは、Oracle Databaseが、1つのタイプの変更のみが行われたと検出した場合に、大幅な最適化を行うためです。
また、複数の表をすべてロードしてからリフレッシュを行うより、表を1つロードするたびにリフレッシュを起動することをお薦めします。
ON
COMMIT
リフレッシュの場合、Oracleは、コミットされたトランザクションで実行されたDMLのタイプを記録します。そのため、同じトランザクションの他の表には、できるだけダイレクト・パス・ロードおよび従来型DMLを実行しないでください。Oracleがリフレッシュ・フェーズを最適化できない可能性があります。たとえば、次のような方法はお薦めできません。
-
ファクト表への新規データのダイレクト・ロード
-
記憶域表へのDML
-
コミット
また、異なるタイプの従来型DML文は、できるだけ混在させないでください。これも、高速リフレッシュ時の様々な最適化を妨げる要因になります。たとえば、次のような文は使用しないでください。
-
ファクト表への挿入
-
ファクト表からの削除
-
コミット
多数の更新が必要な場合は、できるかぎり1回のトランザクションにまとめてください。これによって、リフレッシュは、更新のたびにではなく、コミット時に1回のみですみます。
データ・ウェアハウス環境では、マテリアライズド・ビューがパラレル句を含む場合、次のステップで行うことをお薦めします。
-
ファクト表にバルク・ロードします。
-
パラレルDMLを使用可能にします。
-
ALTER
SESSION
ENABLE
PARALLEL
DML
文を発行します。 -
マテリアライズド・ビューをリフレッシュします。
7.2.3 ネステッド・マテリアライズド・ビューのリフレッシュのヒント
ネステッド・マテリアライズド・ビューのベースとなるオブジェクトは、マテリアライズド・ビューのリフレッシュ時にはすべて通常の表として扱われます。ON
COMMIT
リフレッシュ・オプションが指定されている場合は、すべてのマテリアライズド・ビューがコミット時に適切な順番でリフレッシュされます。Oracleは、一部順序付けられたマテリアライズド・ビューの集合を作成し、リフレッシュ完了後にはすべてのマテリアライズド・ビューが最新になっているように、リフレッシュを行います。マテリアライズド・ビューの状態は、適切なビュー(USER
、DBA_
、ALL_MVIEWS
)に問い合せることでチェックできます。
マテリアライズド・ビューのいずれかがON
DEMAND
リフレッシュとして定義されている場合(リフレッシュ方法がFAST
、FORCE
、COMPLETE
のいずれであるかにかかわらず)、ネステッド・マテリアライズド・ビューは、(最新かどうかにかかわらず)他のマテリアライズド・ビューの現在の内容との比較によってリフレッシュされます。そのため、正しい順番で(マテリアライズド・ビュー間の依存性を考慮して)リフレッシュする必要があります。これには、ネストされた階層の一番上にあるマテリアライズド・ビューに対してリフレッシュ・プロシージャを呼び出し、nested
パラメータをTRUE
に指定します。
コミット中にリフレッシュに失敗した場合は、リフレッシュされていないマテリアライズド・ビューのリストがアラート・ログに書き込まれます。それらをすべて依存マテリアライズド・ビューとともに手動でリフレッシュする必要があります。
ネステッド・マテリアライズド・ビューのリフレッシュには、通常のマテリアライズド・ビューの場合と同じDBMS_MVIEW
プロシージャを使用します。
これらのプロシージャは、ネステッド・マテリアライズド・ビューに対して使用されると、次のように動作します。
-
他のマテリアライズド・ビュー上に作成されているマテリアライズド・ビュー
my_mv
にREFRESH
が適用されると、my_mv
は、nested => TRUE
を指定しないかぎり、他のマテリアライズド・ビューの現在の内容を反映するようにリフレッシュされます(つまり、他のマテリアライズド・ビューが最初にリフレッシュされることはありません)。 -
REFRESH_DEPENDENT
をマテリアライズド・ビューmy_mv
に適用すると、nested => TRUE
を指定しないかぎり、my_mv
に直接依存しているマテリアライズド・ビューのみがリフレッシュされます(my_mv
に依存しているマテリアライズド・ビューにさらに依存しているマテリアライズド・ビューはリフレッシュされません)。 -
REFRESH_ALL_MVIEWS
を使用すると、マテリアライズド・ビューがリフレッシュされる順序は、ネステッド・マテリアライズド・ビュー間の依存性が考慮されます。 -
GET_MV_DEPENDENCIES
で、あるオブジェクトに直接依存するマテリアライズド・ビューのリストが作成されます。
7.2.4 UNION ALLでの高速リフレッシュのヒント
マテリアライズド・ビュー定義にメンテナンス列を指定することで、UNION ALLを使用するマテリアライズド・ビューに高速リフレッシュを使用できます。たとえば、
UNION
ALL
演算子を持つマテリアライズド・ビューは、次のように高速リフレッシュできます。
CREATE MATERIALIZED VIEW fast_rf_union_all_mv AS SELECT x.rowid AS r1, y.rowid AS r2, a, b, c, 1 AS marker FROM x, y WHERE x.a = y.b UNION ALL SELECT p.rowid, r.rowid, a, c, d, 2 AS marker FROM p, r WHERE p.a = r.y;
メンテナンス・マーカー列(例ではMARKER
)の形式は、numeric_or_string_literal
AS
column_alias
である必要があります。ここで各UNION
ALL
メンバーは、numeric_or_string_literal
に対して別個の値を持ちます。
7.2.5 コミットSCNベースのマテリアライズド・ビュー・ログを使用した高速リフレッシュのヒント
実表のマテリアライズド・ビュー・ログにWITH
COMMIT
SCN
句を含めるようにすると、多くの場合、高速リフレッシュのパフォーマンスを大幅に改善できます。WITH
COMMIT
SCN
を使用してマテリアライズド・ビュー・ログの処理を最適化することで、高速リフレッシュの処理時間を短縮できます。次の例は、この句の使用方法を示しています。
CREATE MATERIALIZED VIEW LOG ON sales WITH ROWID (prod_id, cust_id, time_id, channel_id, promo_id, quantity_sold, amount_sold), COMMIT SCN INCLUDING NEW VALUES;
マテリアライズド・ビューのリフレッシュではコミットSCNベースのマテリアライズド・ビュー・ログが自動的に使用されるので、リフレッシュ時間が短縮されます。
COMMIT
SCN
を利用できるのは、新しいマテリアライズド・ビュー・ログのみです。既存のマテリアライズド・ビュー・ログの場合は、削除して再作成しないかぎり、変更してCOMMIT
SCN
を追加できません。
タイムスタンプ・ベースのマテリアライズド・ビュー・ログを使用した実表とコミットSCNベースのマテリアライズド・ビュー・ログを使用した実表の両方でマテリアライズド・ビューが作成されると、エラー(ORA-32414)が発生し、これらのマテリアライズド・ビュー・ログが高速リフレッシュに関して相互に互換性がないことを示すメッセージが表示されます。
7.2.6 マテリアライズド・ビューのリフレッシュ後のヒント
ロードまたは増分ロードを行い、ディテール表索引を再作成した後は、整合性制約(ある場合)を使用可能に戻し、そのディテール表から導出されたマテリアライズド・ビューおよびマテリアライズド・ビュー索引をリフレッシュする必要があります。データ・ウェアハウス環境では、参照整合性制約は、通常、NOVALIDATE
またはRELY
オプションで使用可能にできます。リフレッシュ操作を行う前に、そのリフレッシュ操作をリカバリ可能にする必要があるかどうかを決定する必要があります。マテリアライズド・ビューのデータは冗長で、いつでもディテール表から再作成できるため、マテリアライズド・ビューのロギングは使用禁止にすることをお薦めします。ロギングを無効にし、増分リフレッシュをリカバリの必要なしで実行するには、リフレッシュの前にALTER
MATERIALIZED
VIEW
... NOLOGGING
文を使用します。
ON
COMMIT
方法でマテリアライズド・ビューをリフレッシュする場合は、リフレッシュ操作後、アラート・ログalert_
SID.log
およびトレース・ファイルora_
SID_number.trc
で、エラーが発生していないかどうかをチェックします。
7.3 パーティション表付きマテリアライズド・ビューの使用
データ・ウェアハウスの主なメンテナンス・コンポーネントは、ディテール・データの変更時におけるマテリアライズド・ビューの同期化(リフレッシュ)です。このとき基礎となるディテール表をパーティション化していると、リフレッシュ・タスクの所要時間を短縮できます。これは、パーティション化によりパラレルDMLを使用してマテリアライズド・ビューを更新できるようになるためです。また、パーティション・チェンジ・トラッキングも使用可能になります。
パーティション・チェンジ・トラッキングによるマテリアライズド・ビューの高速リフレッシュでは、PCTリフレッシュに関する追加情報が提供されています。
7.3.1 パーティション・チェンジ・トラッキングによるマテリアライズド・ビューの高速リフレッシュ
データ・ウェアハウスでは、通常、ディテール表の変更により、DROP
、EXCHANGE
、MERGE
およびADD
PARTITION
などのパーティション・メンテナンス操作が必要になります。このような操作の後でマテリアライズド・ビューをメンテナンスするには、手動メンテナンス(CONSIDER
FRESH
も参照)または完全リフレッシュを使用する必要がありました。現在では、パーティション・チェンジ・トラッキング(PCT)リフレッシュと呼ばれる高速リフレッシュ機能を使用できます。
PCTを使用可能にするには、ディテール表をパーティション化する必要があります。この機能では、マテリアライズド・ビュー自体をパーティション化する必要はありません。PCTリフレッシュが可能な場合は、ユーザーに対して透過的に処理が発生します。PCTの要件は、パーティション・チェンジ・トラッキングについてを参照してください。
この機能の使用例を次に示します。
7.3.1.1 マテリアライズド・ビューのPCT高速リフレッシュ: 使用例1
この使用例では、sales
はtime_id
列を使用してパーティション化された表で、products
はprod_category
列でパーティション化されています。表times
はパーティション表ではありません。
この使用例では、高速リフレッシュを行うとPCTリフレッシュが自動的に実行されます。ただし、パーティション・メンテナンス操作によって表が更新され、PCTが不可能な場合には、高速リフレッシュは行われません。これについては、マテリアライズド・ビューのPCT高速リフレッシュ: 使用例2を参照してください。
マテリアライズド・ビューのPCT高速リフレッシュ: 使用例1は、次のように、PMARKER
句を使用してマテリアライズド・ビューを作成した場合にも該当します。
CREATE MATERIALIZED VIEW cust_sales_marker_mv BUILD IMMEDIATE REFRESH FAST ON DEMAND ENABLE QUERY REWRITE AS SELECT DBMS_MVIEW.PMARKER(s.rowid) s_marker, SUM(s.quantity_sold), SUM(s.amount_sold), p.prod_name, t.calendar_month_name, COUNT(*), COUNT(s.quantity_sold), COUNT(s.amount_sold) FROM sales s, products p, times t WHERE s.time_id = t.time_id AND s.prod_id = p.prod_id GROUP BY DBMS_MVIEW.PMARKER(s.rowid), p.prod_name, t.calendar_month_name;
7.3.1.2 マテリアライズド・ビューのPCT高速リフレッシュ: 使用例2
この使用例では、最初の3つのステップは、マテリアライズド・ビューのPCT高速リフレッシュ: 使用例1と同じです。その後、sales
表に対するパーティションのSPLIT
操作を実行します。ただし、マテリアライズド・ビューをリフレッシュする前に、times
表にレコードを挿入します。
PCT高速リフレッシュを実行できない表に対してDMLが発生しているため、このマテリアライズド・ビューは高速リフレッシュできません。この状況を回避するには、パーティション追跡高速リフレッシュが使用可能になっているディテール表に対するパーティション・メンテナンス操作の直後に、高速リフレッシュを実行することをお薦めします。
マテリアライズド・ビューのPCT高速リフレッシュ: 使用例2の状況が発生した場合は、2つの方法が考えられます。つまり、完全リフレッシュを実行するか、後述のようにCONSIDER
FRESH
オプションに切り替えるかです。ただし、CONSIDER
FRESH
とパーティション・チェンジ・トラッキングの高速リフレッシュには、互換性がないため注意する必要があります。ALTER
MATERIALIZED
VIEW
cust_mth_sales_mv
CONSIDER
FRESH
文が発行されると、完全リフレッシュが完了するまで、このマテリアライズド・ビューにはPCTリフレッシュが適用されなくなります。さらに、手動でマテリアライズド・ビューをリフレッシュしないかぎり、CONSIDER
FRESH
を使用しないでください。
データ・ウェアハウスで一般的な状況は、データのローリング・ウィンドウを使用することです。この場合、たとえばディテール表とマテリアライズド・ビューに過去12か月分のデータが含まれる場合があります。毎月、1か月分の新規データが表に追加され、最も古い月が削除(またはアーカイブ)されます。PCTリフレッシュは、この場合にマテリアライズド・ビューをメンテナンスする非常に効率的なメカニズムです。
7.4 ハイブリッド・パーティション表に基づくマテリアライズド・ビューのリフレッシュ
ハイブリッド・パーティション表に基づくマテリアライズド・ビューをリフレッシュするには、完全リフレッシュ方法、高速リフレッシュ方法またはPCTリフレッシュ方法を使用できます。
Oracle Databaseでは外部ソースでのデータのメンテナンス方法を制御できないため、外部パーティションのデータが最新であることは保証されず、その最新状態はUNKNOWNとマークされます。外部パーティションのデータは、信頼できる整合性モードまたは失効許可モードでのみ使用できます。
外部パーティションから発生するデータのリフレッシュは、コストが高くなり、多くの場合は不要な操作となる(ソース・データが変更されていない場合)可能性があります。DBMS_MVIEW.REFRESH
プロシージャのskip_ext_data
属性を使用して、外部パーティションに対応するマテリアライズド・ビュー・データのリフレッシュをスキップできます。この属性をTRUEに設定すると、外部パーティションに対応するマテリアライズド・ビュー・データは再計算されず、状態がUNKNOWNの信頼できるモードのままになります。デフォルトでは、skip_ext_data
はFALSEです。
ノート:
マテリアライズド・ビューの基礎となるハイブリッド・パーティション表でPCTが有効化されていない場合、サポートされるリフレッシュ方法はCOMPLETE
およびFORCE
のみです。FAST
リフレッシュはサポートされません。
例7-6 ハイブリッド・パーティション表に基づくマテリアライズド・ビューのリフレッシュ
マテリアライズド・ビューhypt_mv
の内部パーティションyear_2020
が失効していると仮定します。このマテリアライズド・ビューは、ハイブリッド・パーティション表に基づいています。カタログ・ビューUSER_MVIEW_DETAIL_PARTITION
を問い合せると、次のように表示されます。
SELECT mview_name, detail_partition_name, freshness, last_refresh_time
FROM USER_MVIEW_DETAIL_PARTITION;
MVIEW_NAME DETAIL_PARTITION_NAME FRESHNESS LAST_REFRESH_TIME
---------- --------------------- --------- -----------------
HyPT_MV century_19 UNKNOWN 2018-10-31 20:48:00.20
HyPT_MV century_20 UNKNOWN 2018-10-31 20:48:00.20
HyPT_MV year_2020 STALE 2018-10-31 20:48:00.20
HyPT_MV year_2021 FRESH 2021-10-31 20:48:00.20
次のコマンドを使用して、マテリアライズド・ビューの高速リフレッシュを実行します。
DBMS_MVIEW.REFERSH('HyPT_MV', 'F', skip_ext_data => false);
リフレッシュ後にカタログ・ビューUSER_MVIEW_DETAIL_PARTITION
を問い合せると、次のように表示されます。
SELECT mview_name, detail_partition_name, freshness, last_refresh_time
FROM USER_MVIEW_DETAIL_PARTITION;
MVIEW_NAME DETAIL_PARTITION_NAME FRESHNESS LAST_REFRESH_TIME
---------- --------------------- --------- -----------------
HyPT_MV century_19 UNKNOWN 2018-10-31 20:48:00.20
HyPT_MV century_20 UNKNOWN 2018-10-31 20:48:00.20
HyPT_MV year_2020 FRESH 2021-10-31 21:32:17.00
HyPT_MV year_2021 FRESH 2021-10-31 20:48:00.20
内部パーティションyear_2020
のみがリフレッシュされています。パーティションyear_2021
は、すでに最新であるためリフレッシュされませんでした。skip_ext_data
がFALSEに設定されている場合、外部パーティションの完全リフレッシュおよび内部パーティションの高速リフレッシュが実行されます。
7.5 パーティション化によるデータ・ウェアハウス・リフレッシュの改善
ETL(抽出、変換、ロード)がスケジュールに基づいて実行され、オリジナルのソース・システムに対して行われた変更が反映されます。このステップ中に、新しいクリーン・データを本番データ・ウェアハウス・スキーマに物理的に挿入し、この新しいデータがエンド・ユーザーにも利用できるように、必要に応じてその他のステップ(索引の作成、制約の妥当性チェック、データのバックアップ作成など)をすべて実行します。このデータがすべてデータ・ウェアハウスにロードされた後に、最新データが反映されるようにマテリアライズド・ビューを更新する必要があります。
データ・ウェアハウスのパーティション化方法によって、データ・ウェアハウスのロード・プロセスにおけるリフレッシュ操作の効率が決まります。実際、データ・ウェアハウスの表および索引をパーティション化する方法を選択するときには、ロード・プロセスが重要な考慮点となることがあります。
非常に大規模なデータ・ウェアハウス表(スター・スキーマのファクト表など)のパーティション化方法は、データ・ウェアハウスのロード・パラダイムをベースにする必要があります。
ほとんどのデータ・ウェアハウスには、新しいデータが定期的にロードされます。たとえば、毎晩、毎週、毎月などのペースで、データ・ウェアハウスに新しいデータが格納されます。週末または月末にロードされるデータは、通常、その週またはその月のトランザクションに対応しています。このように、非常に一般的なケースでは、データ・ウェアハウスは時間ごとにロードされます。そのため、データ・ウェアハウス表には、日付列でのパーティション化が適しています。たとえば、次のデータ・ウェアハウスの例では、新しいデータがsales
表に毎月ロードされるとします。また、sales
表は月別にパーティション化されているとします。表sales
に新しい月(2001年1月)のデータを追加するロード・ステップは、次のようになります。
このパーティション化テクニックには、重要な利点があります。第1に、新しいデータのロードに使用するリソースが最小限に抑えられます。新しいデータは、完全に別々の表にロードされるため、索引および制約の処理は、その新しいパーティションのみに適用されます。sales
表が50GBで、12のパーティションを持つとすると、新しい月のデータ・サイズは約4GBになります。索引を作成する必要があるのは新しい月のデータのみです。残りの46GBのデータに関する索引は、まったく変更する必要はありません。このパーティション化方法では、ロード処理時間は、sales
表全体のサイズではなく、新しいデータの量に比例します。
第2に、同時問合せへの影響を最小限に抑えて、新しいデータをロードできます。データのロードに関連する操作は、すべて別のsales_01_2001
表に対して発生しています。したがって、sales
表の既存のデータや索引はデータのリフレッシュ処理中にはまったく影響を受けません。このリフレッシュ処理の間、sales
表およびその索引に、処理が加えられないようにできます。
第3に、グローバル索引が存在する場合は、交換コマンドの一部として段階的にメンテナンスされます。このメンテナンスは、既存のグローバル索引構造の可用性には影響しません。
EXCHANGE操作は、公開機能と見ることができます。データ・ウェアハウスの管理者がsales_01_2001
表をsales
表に交換するまで、エンド・ユーザーは新しいデータを参照できません。EXCHANGEが実行されると、その直後に、sales
表にアクセスするすべてのエンド・ユーザー問合せからsales_01_2001
データが参照できるようになります。
パーティション化は、新しいデータの追加のみでなく、データの削除やアーカイブにも有効です。多くのデータ・ウェアハウスがデータのローリング・ウィンドウを保持しています。たとえば、データ・ウェアハウスには最近36か月のsales
データが格納されているとします。sales
表に新しいパーティションを追加できるのと同じように(前述参照)、古いパーティションも即座に(かつ他に影響を及ぼさずに)sales
表から削除できます。パーティションの追加には2つの効果(リソース使用の削減およびエンド・ユーザーへの影響の最小化)がありますが、これはパーティションの削除にも当てはまります。
パーティション表からデータを削除しても、必ずしも古いデータがデータベースから物理的に削除されるわけではありません。パーティション表からデータを削除するには、他に次の2つの方法があります。1つ目は、古いデータが含まれているパーティションを削除して割り当てられている領域を解放することで、データベースからすべてのデータを物理的に削除する方法です。
ALTER TABLE sales DROP PARTITION sales_01_1998;
2つ目は、古いパーティションを、同じ構造を持つ空の表と交換する方法です。この空の表は、ロード処理のステップ1と2で説明したのと同じステップで作成します。新しい空の表スタブの名前をsales_archive_01_1998
とすると、次のSQL文でパーティションsales_01_1998
が空になります。
ALTER TABLE sales EXCHANGE PARTITION sales_01_1998 WITH TABLE sales_archive_01_1998 INCLUDING INDEXES WITHOUT VALIDATION UPDATE GLOBAL INDEXES;
古いデータは、交換された非パーティション表sales_archive_01_1998
としてまだ存在していることに注意してください。
すべてのパーティションを別々の表領域に格納するという方法でパーティション表が設定されていた場合は、実際のデータ(表領域)を削除する前に、Oracle Databaseのトランスポータブル表領域フレームワークを使用して、この表をアーカイブ(または転送)できます。
場合によっては、古いデータをすぐに削除するのではなく、パーティション表の一部として保持することが必要な場合があります。このデータはもう重要ではありませんが、この古い読取り専用のデータにアクセスする問合せがまだ存在する可能性があります。古いデータの使用領域を最小化するには、Oracleのデータ圧縮を使用できます。1つ以上の圧縮パーティションがすでにパーティション表の一部に含まれていることも想定されます。
関連項目:
-
トランスポータブル表領域の詳細は、トランスポータブル表領域を使用した転送を参照してください。
-
表の圧縮の詳細は、『Oracle Database管理者ガイド』を参照してください。
-
パーティション化と表の圧縮については、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。
7.5.1 データ・ウェアハウスのリフレッシュ・シナリオ
典型的な使用例では、古いデータを圧縮するのみでなく、いくつかの古いパーティションを将来のバックアップの最小処理単位にマージすることが必要な場合があります。バックアップ(パーティション)の最小処理単位がどの四半期についても四半期ベースであり、最も古い月と最新の月の差が36か月より多いものとします。この場合、sales_01_1998
、sales_02_1998
およびsales_03_1998
を新しい圧縮パーティションsales_q1_1998
に圧縮およびマージすることになります。
-
別の表領域に新しいマージ・パーティションをパラレルに作成します。パーティションは、次の
MERGE
操作の一部として圧縮されます。ALTER TABLE sales MERGE PARTITIONS sales_01_1998, sales_02_1998, sales_03_1998 INTO PARTITION sales_q1_1998 TABLESPACE archive_q1_1998 COMPRESS UPDATE GLOBAL INDEXES PARALLEL 4;
-
パーティションの
MERGE
操作により、新しいマージ・パーティションに対するローカル索引は無効になります。したがってこれらを再構築する必要があります。ALTER TABLE sales MODIFY PARTITION sales_q1_1998 REBUILD UNUSABLE LOCAL INDEXES;
かわりに、パーティション表の外部に新しい圧縮表を作成して、これと交換する方法も選択できます。どちらの方法でも、パフォーマンスと一時領域の使用量は同程度です。
どちらの方法も、多少異なるビジネス・シナリオに適用されます。MERGE
PARTITION
を使用する方法では、影響を受けるパーティションのローカル索引構造は無効になりますが、データは常時アクセス可能なまま保たれます。影響を受けるパーティションに対して、使用できない索引構造の1つを介してアクセスしようとすると、エラーが発生します。使用が制限される時間は、ローカル・ビットマップ索引構造を再作成するための時間とほぼ同程度になります。ほとんどの場合、これは無視できます。パーティション表のこの部分はそれほど頻繁にアクセスされないためです。
ただし、CTAS方法では索引構造が使用できない時間はゼロに近く短縮されますが、パーティション表にすべてのデータが揃わない特定の時間枠があります。これは、2つのパーティションを削除したためです。使用が制限される時間は、表を交換するための時間とほぼ同程度になります。グローバル索引の有無およびその数によって、この時間枠は変わります。既存のグローバル索引がない場合、この時間枠はほんの数秒です。
これらの例は、データ・ウェアハウスのローリング・ウィンドウのロードの使用例を単純化したものです。実際のデータ・ウェアハウスのリフレッシュ特性は、さらに複雑です。ただし、このローリング・ウィンドウを使用すると、リフレッシュ特性がさらに複雑になっても、十分な効果を得ることができます。
パーティション表に単一または複数の圧縮パーティションを初めて追加するときは、その前にローカル・ビットマップ索引をすべて削除するか使用不可にマークする必要があることに注意してください。最初に圧縮パーティションを追加した後は、圧縮パーティションに関するその後のどの操作においても追加の処置は必要ありません。これは、どのような方法で圧縮表に圧縮パーティションが追加されたかには関係ありません。
関連項目:
-
パーティション化と表の圧縮については、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。
-
パーティション化と表の圧縮の詳細は、『Oracle Database管理者ガイド』を参照してください。
7.5.2 データ・ウェアハウスのリフレッシュにパーティション化を使用する使用例
この項では、リフレッシュとともにパーティション化が使用される次の2つの典型的なシナリオについて説明します。
7.5.2.1 データ・ウェアハウスのリフレッシュのためのパーティション化: 使用例1
データは毎日ロードされます。ただし、データ・ウェアハウスには2年分のデータを格納するため、1日単位のパーティションは適切ではありません。
ソリューションは、週別または月別(適切な方)にパーティション化することです。INSERT
を使用して、新しいデータを既存のパーティションに追加します。INSERT
操作が影響するパーティションは1つのみなので、前述の利点はそのまま残ります。INSERT
操作は、パーティションが表の一部である場合に行うことができます。単一パーティションへのINSERTはパラレル化できます。
INSERT /*+ APPEND*/ INTO sales PARTITION (sales_01_2001) SELECT * FROM new_sales;
このsales
パーティションの索引もパラレルでメンテナンスされます。このメソッドのかわりにEXCHANGE
操作を使用することもできます。そのためには、sales
表のsales_01_2001
パーティションを交換し、INSERT
操作を使用します。この方法を使用するのは、索引をメンテナンスするよりも、削除して再作成する方が効率的な場合です。
7.5.2.2 データ・ウェアハウスのリフレッシュのためのパーティション化: 使用例2
新しいデータは、主に最近の日、週、月などのものから構成されますが、以前の期間のデータも含まれます。
解決策 1
パラレルSQL操作(CREATE
TABLE
... AS
SELECT
など)を使用して、新しいデータを以前の期間のデータから分離します。日付が古いデータは、他のテクニックを使用して別に処理します。
新しいデータは、必ず時間ベースであるとは限りません。データ・ウェアハウスがビジネス・ニーズに基づいて複数の業務系システムから新規データを受け取るようにすることもできます。たとえば、直接チャネルからの売上データが、間接チャネルからのデータとは別にデータ・ウェアハウスに格納されることもあります。また、業務上の理由から、直接データと間接データを別のパーティションに保存することも適しています。
解決策2
Oracleでは、コンポジット・レンジ-リスト・パーティション化をサポートしています。sales表の主要なパーティション化方法は、例に示すようにtime_id
に基づいたレンジ・パーティション化にできます。ただし、サブパーティション化は、チャネル属性に基づいたリストです。これで各サブパーティションを互いに(それぞれ別個のチャネルごとに)独立にロードして、前述のローリング・ウィンドウ操作で追加できます。パーティション化方式は、最も最適化された方法でビジネス・ニーズを処理します。
7.6 リフレッシュ中のDML操作の最適化
DMLパフォーマンスは、次の方法で最適化できます。
7.6.1 効率的なMERGE操作の実装
ソース・システムから抽出したデータは、データ・ウェアハウスに挿入する必要のある新しいレコードの単なるリストではありません。この新しいデータセットは、新しいレコードと変更レコードの組合せで構成されます。たとえば、OLTPシステムから抽出したデータのほとんどが新しい売上トランザクションによるものだとします。これらのレコードは、ウェアハウスのsales
表に挿入されますが、その中には、商品の返品や、最初にデータ・ウェアハウスにロードしたときに不備があったトランザクションの修正など、以前のトランザクションに対する変更を反映しているものがある場合があります。このようなレコードについては、sales
表の更新が必要です。
new_sales
表があり、この表にsales
表に適用される挿入項目と更新項目の両方が格納されている例を考えてみます。データ・ウェアハウスのロード・プロセス全体を設計するときに、次のような処理方法で、このnew_sales
表にレコードを格納することにします。
-
new_sales
表のレコードの任意のsales_transaction_id
がsales
表にすでに存在する場合、new_sales
表からsales_dollar_amount
およびsales_quantity_sold
の値をsales
表の既存の行に追加することで、sales
表を更新します。 -
それ以外の場合は、
new_sales
表から新しいレコード全体をsales
表に挿入します。
このUPDATE-ELSE-INSERT
操作は、通常はマージと呼ばれます。マージは、1つのSQL文で実行できます。
例7-7 MERGE操作
MERGE INTO sales s USING new_sales n ON (s.sales_transaction_id = n.sales_transaction_id) WHEN MATCHED THEN UPDATE SET s.sales_quantity_sold = s.sales_quantity_sold + n.sales_quantity_sold, s.sales_dollar_amount = s.sales_dollar_amount + n.sales_dollar_amount WHEN NOT MATCHED THEN INSERT (sales_transaction_id, sales_quantity_sold, sales_dollar_amount) VALUES (n.sales_transcation_id, n.sales_quantity_sold, n.sales_dollar_amount);
ターゲット表に対する無条件のUPDATE
ELSE
INSERT
機能でMERGE
文を使用することに加えて、次のことも可能です。
-
UPDATE
のみ、またはINSERT
のみの文を実行する。 -
追加の
WHERE
条件をMERGE
文のUPDATE
またはINSERT
部分に適用する。 -
特定の条件がTRUEの場合、
UPDATE
操作で行を削除する。
例7-8 INSERT句の省略
一部のデータ・ウェアハウス・アプリケーションでは、新しい行を履歴情報に追加することはできず、更新のみが可能なものがあります。また、更新ではなく新しい情報の挿入のみが必要な場合があります。次の文は、UPDATE
のみ使用してINSERT
機能のみを実行する例です。
MERGE USING Product_Changes S -- Source/Delta table INTO Products D1 -- Destination table 1 ON (D1.PROD_ID = S.PROD_ID) -- Search/Join condition WHEN MATCHED THEN UPDATE -- update if join SET D1.PROD_STATUS = S.PROD_NEW_STATUS
例7-9 UPDATE句の省略
次の文は、UPDATE
を省略する例です。
MERGE USING New_Product S -- Source/Delta table INTO Products D2 -- Destination table 2 ON (D2.PROD_ID = S.PROD_ID) -- Search/Join condition WHEN NOT MATCHED THEN -- insert if no join INSERT (PROD_ID, PROD_STATUS) VALUES (S.PROD_ID, S.PROD_NEW_STATUS)
INSERT
句を省略した場合は、ソース表とターゲット表に対して通常の結合が実行されます。UPDATE
句を省略した場合は、ソース表とターゲット表に対してアンチ結合が実行されます。これによって、ソース表とターゲット表がより効率的に結合されます。
例7-10 UPDATE句のスキップ
特定の行を表にマージする際に、UPDATE
操作をスキップしなければならない場合があります。この場合、MERGE
のUPDATE
句にオプションのWHERE
句を使用できます。その結果、UPDATE
操作は、指定した条件がTRUEの場合にのみ実行されるようになります。次の文は、UPDATE
操作をスキップする例を示しています。
MERGE USING Product_Changes S -- Source/Delta table INTO Products P -- Destination table 1 ON (P.PROD_ID = S.PROD_ID) -- Search/Join condition WHEN MATCHED THEN UPDATE -- update if join SET P.PROD_LIST_PRICE = S.PROD_NEW_PRICE WHERE P.PROD_STATUS <> "OBSOLETE" -- Conditional UPDATE
次に、条件P.PROD_STATUS <> "OBSOLETE"
がTRUEではない場合にUPDATE
操作がどのようにスキップされるかを示します。条件の述語は、ターゲット表とソース表の両方を指すことができます。
例7-11 MERGE文の条件付き挿入
特定の行を表にマージする際に、INSERT
操作をスキップしなければならない場合があります。この場合、MERGE
のINSERT
句にオプションのWHERE
句を追加します。その結果、INSERT
操作は、指定した条件がTRUEの場合にのみ実行されるようになります。次に例を示します。
MERGE USING Product_Changes S -- Source/Delta table INTO Products P -- Destination table 1 ON (P.PROD_ID = S.PROD_ID) -- Search/Join condition WHEN MATCHED THEN UPDATE -- update if join SET P.PROD_LIST_PRICE = S.PROD_NEW_PRICE WHERE P.PROD_STATUS <> "OBSOLETE" -- Conditional WHEN NOT MATCHED THEN INSERT (PROD_ID, PROD_STATUS, PROD_LIST_PRICE) -- insert if not join VALUES (S.PROD_ID, S.PROD_NEW_STATUS, S.PROD_NEW_PRICE) WHERE S.PROD_STATUS <> "OBSOLETE"; -- Conditional INSERT
この例は、条件S.PROD_STATUS <> "OBSOLETE"
がTRUEではない場合にINSERT
操作がスキップされ、条件がTRUEのときにのみINSERT
が実行されることを示します。条件の述語は、ソース表のみを指すことができます。条件の述語は、ソース表のみを指すことができます。
例7-12 MERGE文でのDELETE句の使用
表を移入または更新する際に、表をクレンジングする場合があります。この場合、次の例のように、MERGE
文でDELETE
句を使用できます。
MERGE USING Product_Changes S INTO Products D ON (D.PROD_ID = S.PROD_ID) WHEN MATCHED THEN UPDATE SET D.PROD_LIST_PRICE =S.PROD_NEW_PRICE, D.PROD_STATUS = S.PROD_NEWSTATUS DELETE WHERE (D.PROD_STATUS = "OBSOLETE") WHEN NOT MATCHED THEN INSERT (PROD_ID, PROD_LIST_PRICE, PROD_STATUS) VALUES (S.PROD_ID, S.PROD_NEW_PRICE, S.PROD_NEW_STATUS);
このように、行がproducts
で更新される際に、削除条件D.PROD_STATUS = "OBSOLETE"
がチェックされ、条件がTRUEであれば行が削除されます。
DELETE
操作は、完全なDELETE
文の削除とは異なります。MERGE
先の行のみが削除されます。DELETE
の影響を受ける行のみが、このMERGE
文で更新される行です。したがって、目的の表で指定した行が削除条件に合致しても、ON
句の条件の下で結合を実行しない場合は削除されません。
例7-13 MERGE文の無条件の挿入
ソースのすべての行を表に挿入する場合があります。この場合、ソース表とターゲット表の結合を避けることができます。1=0など、常にFALSE
になる特殊な一定の結合条件を指定することで、このようなMERGE
文は最適化され、結合条件は無効になります。
MERGE USING New_Product S -- Source/Delta table INTO Products P -- Destination table 1 ON (1 = 0) -- Search/Join condition WHEN NOT MATCHED THEN -- insert if no join INSERT (PROD_ID, PROD_STATUS) VALUES (S.PROD_ID, S.PROD_NEW_STATUS)
7.6.2 データ・ウェアハウスの参照整合性の維持
データ・ウェアハウス環境によっては、参照整合性を保証するために新しいデータを表に挿入する必要がある場合もあります。たとえば、キャッシュ・レジスタから直接データを取り出す業務系システムからsales
を導出するデータ・ウェアハウスがあるとします。sales
は毎晩リフレッシュされます。ただし、product
ディメンション表のデータは別の業務系システムから導出されます。product
ディメンション表の変更には比較的時間がかかるため、この表は週に1回しかリフレッシュされないことがあります。新製品が月曜日に導入されたとすると、その製品の
product_id
がデータ・ウェアハウスのproduct
表に挿入される前に、データ・ウェアハウスのsales
データ内にproduct_id
が表示される可能性があります。
この新製品の売上トランザクションは有効ですが、その売上データは、product
ディメンション表とsales
ファクト表間の参照整合性制約を満たしません。この場合、新しい売上トランザクションを禁止するより、sales
表にその売上トランザクションを挿入する方を選ぶのが普通です。ただし、sales
表とproduct
表間の参照整合性関係もメンテナンスする必要があります。これは、新しい行を不明な製品のプレースホルダとしてproduct
表に挿入することによって可能になります。
前述の例のように、sales
表への新しいデータは別のnew_sales
表に格納されるとします。パラレル化が可能な単一のINSERT
文で、product
表が新製品を反映するように変更できます。
INSERT INTO product (SELECT sales_product_id, 'Unknown Product Name', NULL, NULL ... FROM new_sales WHERE sales_product_id NOT IN (SELECT product_id FROM product));
7.6.3 データ・ウェアハウスからのデータのパージ
データ・ウェアハウスから大量のデータを削除する必要がある場合もあります。前述のローリング・ウィンドウでは、古いデータをデータ・ウェアハウスからロールアウトして新しいデータの領域を確保するという、非常に一般的な例を取り上げました。
ただし、それ以外の場合でも、データをデータ・ウェアハウスから削除する必要がある場合があります。たとえば、ある小売会社が、以前にXYZ
Software
社の製品を販売し、その後XYZ
Software
が廃業したとします。データ・ウェアハウスを業務で利用しているユーザーが、XYZ
Software
社に関するデータはもう必要ないと判断し、このデータを削除することになりました。
大量のデータを削除する方法の1つに、パラレル削除による方法があります。例を次に示します。
DELETE FROM sales WHERE sales_product_id IN (SELECT product_id FROM product WHERE product_category = 'XYZ Software');
このSQL文では、パーティションごとに1つのパラレル処理が起動されます。このアプローチは一連のDELETE
文よりもはるかに効率的であり、sales
表内のデータを移動する必要はありません。ただし、いくつかのデメリットもあります。行の大部分を削除する場合、DELETE
文は既存のパーティションに多数の行スロットを残します。その後、新しいデータがローリング・ウィンドウ・テクニックによってロードされても(またはダイレクト・パス・インサートまたはダイレクト・パス・ロードによってロードされても)、この記憶領域は再使用されません。また、
DELETE
文はパラレル化できますが、それより効率的な方法もあります。別の方法としては、XYZ
Software
社以外の製品カテゴリのデータをすべて維持したまま、sales
表全体を再作成する方法があります。
CREATE TABLE sales2 AS SELECT * FROM sales, product WHERE sales.sales_product_id = product.product_id AND product_category <> 'XYZ Software' NOLOGGING PARALLEL (DEGREE 8) #PARTITION ... ; #create indexes, constraints, and so on DROP TABLE SALES; RENAME SALES2 TO SALES;
この方法は、パラレルDELETEより効率的です。ただし、sales
表を2回インスタンス化することになるため、この方法もディスク領域の使用量の面ではコストが高くなります。
ディスク領域の使用量が少ない別の方法として、sales
表を一度に1パーティションずつ再作成する方法があります。
CREATE TABLE sales_temp AS SELECT * FROM sales WHERE 1=0; INSERT INTO sales_temp SELECT * FROM sales PARTITION (sales_99jan), product WHERE sales.sales_product_id = product.product_id AND product_category <> 'XYZ Software'; <create appropriate indexes and constraints on sales_temp> ALTER TABLE sales EXCHANGE PARTITION sales_99jan WITH TABLE sales_temp;
sales
表の各パーティションに対して、このプロセスを繰り返します。