このチュートリアルでは、Oracle Database 11gで新しく導入されたパーティション化技術を使用する方法について紹介します。
約60分
このチュートリアルでは、以下のトピックについて説明します。
| 概要 | |
| 前提条件 | |
| 参照パーティション化の使用 | |
| インターバル・パーティション化の使用 | |
| 表パーティションの名前の変更 | |
| 表パーティションの交換 | |
| 拡張コンポジット・パーティション化の使用 | |
| 仮想列ベース・パーティション化の使用 | |
| まとめ |
このアイコンの上にカーソルを置くと、すべてのスクリーンショットがロードし、表示されます。
(警告:すべてのスクリーンショットが同時にロードされるため、ご使用のインターネット接続によってはレスポンス・タイムが遅くなる場合があります。)
注:各手順に関連したスクリーンショットのみを表示する場合は、それぞれの手順にあるアイコンの上にカーソルを置いてください。 スクリーンショットをクリックすると、非表示になります。
Oracle Database 11gでは、データの取得パフォーマンスと編成を向上させるため、表データのパーティション化のための新技術が多数導入されています。 導入されている新技術は、次のとおりです。
| 参照パーティション化 | キー列を複製せずに親の表からパーティション・キーを継承することで、親子関係にある表を論理的に同一レベル・パーティション化する |
| インターバル・パーティション化 | レンジ・パーティションの作成を自動化する |
| 拡張コンポジット・パーティション化 | 2次元で論理的なレンジ・パーティション化を有効にする |
| 仮想列パーティション化 | 表の仮想列に対してパーティション・キー列を定義する |
このチュートリアルを始める前に、次のことを確認してください。
| 1. | Oracle Database 11gをインストールしていること。 |
|
| 2. | partition.zipファイルをダウンロードし、作業ディレクトリに解凍していること。 |
|
| 3. | ターミナル・ウィンドウから次のコマンドを実行していること。 sqlplus / as sysdba @setup
|
|
参照パーティション化を使用すると、キー列を複製せずに親表からパーティション・キーを継承することで、親子関係にある表を論理的に同一レベルでパーティション化できます。 パーティション化キーは既存の親子関係を介して解決され、アクティブな主キーまたは外部キーの制約によって実行されます。 また、論理的依存性によってパーティションの保守処理と自動的に関連付けられるため、アプリケーション開発が簡単になり、エラーの発生を抑えることができます。
参照パーティション化の使用法について詳しく理解するには、次の手順を実行します。
| 1. |
ターミナル・ウィンドウを開き、SHユーザーとしてSQL*Plusにログインします。 create_orders.sqlスクリプトを実行して、レンジ・パーティション化されたORDERS表を作成します。 @create_orders
|
| 2. |
create_order_items.sqlスクリプトを実行して、参照パーティション化されたORDER_ITEMS表を作成します。 @create_order_items
|
| 3. |
query_dict_1.sqlスクリプトを実行して、参照パーティション化されたORDER_ITEMS表の情報を参照します。 @query_dict_1
|
| 4. |
insert_orders.sqlスクリプトを実行して、データをORDERS表に挿入します。 @insert_orders
|
| 5. |
show_data_placement.sqlスクリプトを実行して、パーティション内でどのようにデータがコロケートされたかを確認します。 @show_data_placement
|
| 6. |
パーティションワイズ結合を表示するには、_parallel_broadcast_enabledパラメータをFALSEに設定します。 次のコマンドを実行します。 ALTER SESSION SET "_parallel_broadcast_enabled"=FALSE; 注:パラレル・パーティションワイズ結合は、2つの大きなパーティション表を並列に結合する際に非常に効率的な結合です。 このチュートリアルでは非常に大きなデータセットは使用しないため、パラレル・パーティションワイズ結合を使用した実行計画がどのようなものであるかを示すために、_parallel_broadcast_enabledパラメータをFalseに設定し、問合せでハッシュ結合ヒントを使用しています。 実際の環境では、パラレル・パーティションワイズ結合を表示するためにパラメータを設定したり、ヒントを使用したりする必要はありません。
|
| 7. |
show_plan.sqlスクリプトを実行して、パーティションワイズ結合に関する情報を表示します。 @show_plan
|
| 8. |
drop_partition.sqlスクリプトを実行して、p_before_jan_2006パーティションをORDERS表から削除します。 @drop_partition
|
| 9. |
query_dict_2.sqlスクリプトを実行して、表の情報を表示します。 @query_dict_2
|
| 10. |
add_partition.sqlスクリプトを実行して、p2007_01パーティションを追加します。 注: 親表に2つのパーティションが追加されました。2つ目のパーティションでは"dependent tables"句を使用して、子表パーティションに対して異なる表領域の割当てが使用されています。 @add_partition
|
| 11. |
cleanup_1.sqlスクリプトを実行して、このシナリオで作成したパーティションと表領域を削除します。 @cleanup_1
|
新しいインターバル・パーティション化の手法は、レンジ・パーティション化を拡張したものです。 インターバル・パーティション化を使用すると、レンジ・パーティションの作成が完全に自動化されます。 言い換えると、必要なときに新しいパーティションが作成されます。 インターバル基準を定義すると、挿入されたデータがすべてのレンジ・パーティションを超えた場合に、データベースによって自動的に新しいパーティションが作成されます。 新規パーティション作成の管理は、煩雑で非常に繰り返しの多い作業です。 これは特に、毎日新しいパーティションを追加している場合などの、予測可能な小規模レンジ・パーティションの追加に当てはまります。 インターバル・パーティション化は、オンデマンドでパーティションの作成をすることで、この処理を自動化します。 インターバル・パーティション化を使用する前に、少なくとも1つのレンジ・パーティションを作成しておく必要があります。
インターバル・パーティション化の使用法について理解するには、次の手順を実行します。
| 1. |
create_newsales.sqlスクリプトを実行して、NEWSALESインターバル・パーティション表を作成します。 前述のとおり、インターバル・パーティション化はレンジ・パーティション化を拡張したものです。 インターバル・パーティション化の場合、パーティション・キーは表に含まれる1つの列名であり、かつデータ型がNUMBERまたはDATEでなければなりません。 次の例では、パーティション・キーとしてDATEデータ型を使用しています。 @create_newsales
上のスナップショットに含まれるINTERVAL句によって、インターバルが定義されます。 時間に関するインターバルのサイズを表すために、新しい日付関数が導入されています。 上の例では、1日というインターバルが定義されており、 表の作成時に、レンジ・パーティションが作成されます。 Interval句にはSTORE INというオプション句があり、このオプション句には1つ以上の表領域を指定できます。インターバル・パーティションが後から作成されると、データベースはラウンドロビン・アルゴリズムに従ってこの表領域にインターバル・パーティション・データを格納します。 表領域は、インターバル番号によって決定されます。 STORE INオプション句の構文は次のとおりです。 ... INTERVAL (NUMTODSINTERVAL(1,'DAY')) STORE IN (tbs1, tbs2, tbs3, tbs4) ...
|
| 2. |
query_dict_3.sqlスクリプトを実行して、新しく作成されたNEWSALES表に関する情報をUSER_TAB_PARTITIONSディクショナリ・ビューに問い合わせます。 このビューはパーティション・レベルのパーティション化情報やパーティション・ストレージ・パラメータ、またDBMS_STATSパッケージやANALYZE文によって生成されたパーティション統計情報を表示します。 @query_dict_3
|
| 3. |
insert_newsales.sqlスクリプトを実行して、NEWSALES表に新しいデータを挿入します。 新しく挿入された10個の行は1月1日以降の日付を示しているため、6つの新しいパーティションが自動的に作成されています。 @insert_newsales
|
| 4. |
query_dict_4.sqlスクリプトを実行して、10行が挿入された際にシステムによって自動作成された6つの新しいパーティションに関する情報を表示します。 パーティションの上位境界が移行ポイントを表しており、その境界以下にあるすべてのパーティションはレンジ・セクションに含まれます。またこの境界を超えるすべての将来的なパーティション(2005年1月1日以降)は、インターバル・セクションに当てはまります。 新しいパーティションの名前はシステムによって生成され、接頭辞sys_で始まります。 この例で新しく作成されたインターバル・パーティションは、次のとおりです。 SYS_P41: 2005年1月1日に新しく挿入されたnewsalesデータを含み、最初にシステムによって作成されたインターバル・パーティション SYS_P42: 2005年1月2日に新しく挿入されたnewsalesデータを含み、2番目にシステムによって作成されたインターバル・パーティション SYS_P43: 2005年1月5日に新しく挿入されたnewsalesデータを含み、3番目にシステムによって作成されたインターバル・パーティション SYS_P44: 2005年1月6日に新しく挿入されたnewsalesデータを含み、4番目にシステムによって作成されたインターバル・パーティション SYS_P45: 2005年1月9日に新しく挿入されたnewsalesデータを含み、5番目にシステムによって作成されたインターバル・パーティション SYS_P46: 2005年1月10日に新しく挿入されたnewsalesデータを含み、6番目にシステムによって作成されたインターバル・パーティション @query_dict_4
|
| 5. |
merge_partition.sqlスクリプトを実行して、パーティションSYS_P41とSYS_P42をマージします。 2つのインターバル・パーティションをマージすると、完了済みのインターバル・パーティションSYS_P41とSYS_P42はシステムによって自動的にレンジ・パーティションに変換されます。 移行ポイントはレンジ・セクションの末尾に移動されます。 新しいFOR句を使用すると、名前を知らなくても特定のパーティションを指定できます。 @merge_partition
インターバル・パーティションをマージすると、マージされた2つのパーティションの高いほうの上位境界に移行ポイントが移動されます。 つまり、インターバル・パーティション表のレンジ・セクションが、マージされた2つのパーティションの上位境界まで拡張されます。 新しくマージされたパーティションよりも低位の境界を持つマテリアライズド・インターバル・パーティションがある場合、このパーティションは自動的にレンジ・パーティションに変換され、その上位境界はインターバルの上位境界によって定義されます。
|
| 6. |
query_dict_5.sqlスクリプトを実行して、マージされたパーティションの情報を表示します。 新しいパーティションの名前は、P_BEFORE_3_JAN_2005です。 @query_dict_5
|
| 7. |
create_hist_newsales.sqlスクリプトを実行して、レンジ・パーティション表を作成します。 @create_hist_newsales
|
| 8. |
query_dict_6.sqlスクリプトを実行して、新しく作成されたパーティションの情報を表示します。 @query_dict_6
|
| 9. |
insert_histnewsales_row_1.sqlスクリプトを実行して、HISTORICAL_NEWSALES表に行を挿入します。 パーティション表は現在インターバル・パーティション表ではないため、挿入は失敗します。 @insert_histnewsales_row_1
|
| 10. |
alter_hist_newsales.sqlスクリプトを実行して、パーティション表をインターバル・パーティション表へ変更します。 @alter_hist_newsales
|
| 11. |
insert_histnewsales_row_2.sqlスクリプトを実行して、再度この表に行を挿入します。 @insert_histnewsales_row_2
|
| 12. |
query_dict_7.sqlスクリプトを実行して、パーティションに関する情報を表示します。 システムによって新しく作成されたインターバル・パーティションの名前は、SYS_P<##>です。 @query_dict_7
|
インターバル・パーティション表に含まれるインターバル・パーティションを削除できます。 この操作を実行するとインターバルのデータのみが削除され、インターバル定義はそのまま残ります。 削除されたインターバルにデータが挿入されると、データベースによって再度インターバル・パーティションが作成されます。 また、インターバル・パーティション表に含まれるレンジ・パーティションを削除することもできます。 ただし、インターバル・パーティション表のレンジ・パーティション・セクションの最上位にあるレンジ・パーティションを削除することはできません。
SET INTERVAL句に空白の値を使用すると、将来的なインターバル・パーティションの作成を無効化し、実質的にレンジ・パーティション表に戻すことができます。 作成済みのインターバル・パーティションは、現在の上限値を持つレンジ・パーティションに変換されます。 また、SET INTERVAL句を使用して、既存のレンジ・パーティション表またはレンジ*コンポジット・パーティション表をインターバルまたはインターバル*パーティション表に移行することもできます。
表パーティションや索引パーティション、またサブパーティションの名前を変更して、別の保守操作内で割り当てられたデフォルトのシステム名の代わりに意味のある名前を割り当てることができます。 すべてのパーティション化手法で、パーティションを特定するためにFOR(値)句を使用できます。 この方法を使用すると、システム生成のパーティション名をより意味のある名前に変更できます。 これは特に、インターバルまたはインターバル*パーティション表に有効です。 参照パーティション化されたマスター表と子表に対して、パーティションやサブパーティションの名前を単独で変更できます。 マスター表に対する名前変更操作は、子孫表にカスケードされません。
ALTER TABLE ... RENAME PARTITION文を使用して、レンジ・パーティションやハッシュ・パーティション、またはリスト・パーティションの名前を変更できます。 この項では、インターバル・パーティション化の項で作成されたシステム生成パーティションの名前を変更します。
| 1. | 既存のパーティションを確認するため、すでに実行したquery_dict_7.sqlスクリプトを再実行します。 @query_dict_7
|
| 2. | パーティションの名前を変更するには、次のコマンドを実行します。 ALTER TABLE historical_newsales RENAME PARTITION sys_p<##> TO P_2006_p<##>; ここでsys_p<##>は、手順1の問合せで取得されたシステム生成パーティションです。
|
| 3. | query_dict_7.sqlスクリプトを再実行して、パーティション表の名前が変更されたことを確認します。 @query_dict_7
|
データ・セグメントを交換すると、パーティション(またはサブパーティション)から非パーティション表へ、また非パーティション表からパーティション表のパーティション(またはサブパーティション)へと変換できます。 表パーティションの交換は、アプリケーションで使用している非パーティション表からパーティション表のパーティションへと変換したい場合にもっとも有効です。 たとえばデータウェアハウス環境でパーティションを交換すると、既存のパーティション表に対する新規増分データのロードが高速化されます。 一般に、OLTP環境やデータウェアハウス環境で、パーティション表に含まれる古いデータ・パーティションを交換すると利点がもたらされます。 データは実際に削除されることなくパーティション表から消去され、後から別々にアーカイブできます。 パーティションを交換しても、ロギング属性は保持されます。 また、ローカル索引を含めて交換するかどうか(INCLUDING INDEXES句)や、行の正しいマッピングを検証するかどうか(WITH VALIDATION句)を任意で指定できます。
インターバル・パーティション表に含まれるインターバル・パーティションを交換できます。 ただし、パーティションを交換する前に、インターバル・パーティションが作成されていることを確認する必要があります。 インターバル・パーティションをロックすると、データベースによるパーティション作成を実行できます。 次の例では、月次パーティションを使用してインターバル・パーティション化されたhistorical_newsales表に対するパーティション交換を示します。 この例では、パーティション交換ロードを使用して、2007年1月のデータを表に追加する方法について説明します。 historical_newsales表にはローカル索引のみが作成されており、同等の索引がhistorical_newsales2表にも作成されているとします。 次の手順を実行してください。
| 1. | 交換データをロードするためのもう1つのパーティションを作成するには、lock_hist_newsales.sqlスクリプトを実行します。 @lock_hist_newsales
|
| 2. | query_dict_7.sqlスクリプトを再実行して、新規パーティションの情報を表示します。 @query_dict_7
|
| 3. | 次に、パーティション化されていない新規表を作成し、データ行を挿入します。create_hist_newsales2.sql スクリプトを実行します。 @create_hist_newsales2
|
| 4. | 交換を実行する前に、historical_newsalesデータに含まれるデータを表示します。 次のコマンドを実行します。 select * from historical_newsales;
|
| 5. | これで、交換を実行する準備ができました。 exchange_hist_newsales.sqlスクリプトを実行します。 @exchange_hist_newsales
|
| 6. | 次のコマンドを実行して、historical_newsales表とhistorical_newsales2表の内容を表示します。 select * from historical_newsales;
|
| 7. | query_dict_7.sqlスクリプトをもう一度再実行します。 '02-JAN-07'は2008年1月1日より以前のデータであるため、今回はhistorical_newsales表内のシステム生成パーティションであるSYS_P118に含まれることを確認します。 @query_dict_7
|
参照パーティション化された表に含まれるパーティションを交換することもできますが、参照するデータが親表内の各パーティションに含まれることを確認する必要があります。
仮想列を含む場合も、パーティション交換を実行できます。 仮想列を含むパーティション表でパーティションを交換するには、パーティション表の1つのパーティション内のすべての非仮想列の定義と一致する表を作成する必要があります。 仮想列に制約または索引が定義されていない限り、仮想列の定義を含む必要はありません。 このような定義が含まれる場合、パーティション表の制約や索引定義と一致させるには、仮想列定義を含む必要があります。 このシナリオは、仮想列ベースのパーティション表にも当てはまります。
コンポジット・レンジ間パーティション化は、2次元での論理的なレンジ・パーティション化を実現します。たとえば、ORDER_DATEでパーティション化し、SHIPPING_DATEでレンジ・サブパーティション化できます。 コンポジット・レンジ間パーティション化を利用すると、ビジネス要件をオブジェクトのパーティション化にマッピングする際の新たなモデリング戦略が得られます。
この例では、注文を受けると1カ月以内に納品するという品質保証契約が顧客との間に規定されています。 次に、注文の種類を示します。
| 早期納品 | 注文を受けた後、半月以内で納品される注文。 これらの注文は、顧客の期待を上回る可能性があります。 |
| 合意済み納品 | 注文を受けた後、1カ月以内に配達される注文(早期納品ではない)。 |
| 納期遅れ | 注文を受けた後、1カ月以上経ってから納品される注文。 |
以下の手順を実行して、ビジネス要件を満たすレンジ間コンポジット・パーティション表を作成します。
| 1. |
create_shipments.sqlスクリプトを実行し、ORDER_DATEとSHIPDATEを使用したレンジ間コンポジット・パーティション表であるSHIPMENTS表を作成します。 @create_shipments
|
| 2. |
insert_shipments.sqlスクリプトを使用して、SHIPMENTS表に行を挿入します。 @insert_shipments
|
| 3. |
count_shipments.sqlスクリプトを実行して、SHIPMENTS表内でデータがどのように分散されたかを確認します。 @count_shipments
|
仮想列パーティション化を、表の仮想列に定義されたパーティション・キー列に対して使用できます。 仮想列は、式の検証を使用して、 表を作成または変更する際に定義されます。 論理的パーティション・オブジェクトに対するビジネス要件は往々にして、既存の列と1対1で適合しません。 Oracleのパーティション化は、仮想列に対してパーティション化を定義できるように拡張されているため、ビジネス要件をより包括的に満たします。
この例では、従業員は以下のカテゴリに分類されています。
| 不十分 | 給料の合計(給料+歩合)が1,000未満 |
| やや不十分 | 給料が1,000から3,000の間 |
| 目標どおり | 給料が3,000 |
| 目標超え | 給料が3,000以上 |
仮想列ベースのパーティション化の使用法について理解するには、次の手順を実行します。
| 1. |
create_employees.sqlスクリプトを実行して、仮想列を含むEMPLOYEES表を作成します。 @create_employees
|
| 2. |
insert_employees.sqlスクリプトを実行して、EMPLOYEES表に行を挿入します。 @insert_employees
|
| 3. |
select_employees.sqlスクリプトを実行して、EMPLOYEES表に対する問合せを実行します。 @select_employees
. . .
|
| 4. |
create_prod_ret.sqlスクリプトを実行し、仮想列を使用してパーティション化されたPRODUCT_RETURNS表を作成します。 @create_prod_ret
|
| 5. |
insert_prod_ret.sqlスクリプトを実行して、PRODUCT_RETURNS表に行を挿入します。 @insert_prod_ret
. . .
|
| 6. |
select_prod_return.sqlスクリプトを実行して、PRODUCT_RETURNS表に対する問合せを実行します。 @select_prod_return
|
| 7. |
xplan_prod_ret.sqlスクリプトを実行し、仮想列を定義する式を使用した問合せに対するパーティション・プルーニングを表示します。 @xplan_prod_ret
|
このチュートリアルで学習した内容は、次のとおりです。
| 参照パーティション化の使用 | ||
| インターバル・パーティション化の使用 | ||
| 表パーティションの名前の変更 | ||
| 表パーティションの交換 | ||
| 拡張コンポジット・パーティション化の使用 | ||
| 仮想列パーティション化の使用 | ||