プライマリ・コンテンツに移動
Oracle® Databaseデータ・ウェアハウス・ガイド
12c リリース1 (12.1)
B71318-06
目次へ移動
目次
索引へ移動
索引

前
次

4 データ・ウェアハウスの最適化および技法

この章では、データ・ウェアハウスのスキーマについて説明します。内容は次のとおりです。

データ・ウェアハウスでの索引の使用方法

索引を使用すると、データ・ウェアハウスに格納されたデータをより迅速に取得できます。この項ではデータ・ウェアハウスで索引を使用する際の次の側面について説明します。

データ・ウェアハウスでのビットマップ索引の使用について

ビットマップ索引は、データ・ウェアハウス環境で広く使用されています。この環境では、通常、データおよび非定型の問合せは大量にありますが、同時DMLトランザクションは低いレベルです。このようなアプリケーションでは、ビットマップ索引による次のメリットがあります。

  • 大規模な非定型問合せに対する応答時間が削減されます。

  • 他の索引付けテクニックと比較すると、領域の使用量が少なくて済みます。

  • 比較的CPUの数が少ないハードウェアまたはメモリー量が少ないハードウェアでも、大幅にパフォーマンスが向上します。

大規模な表を従来のBツリー索引で完全に索引付けすると、索引が、表にあるデータの数倍の大きさになる場合があるため、ディスク領域の点で非常にコストが高くなります。通常、ビットマップ索引のサイズは、表内の索引付けされたデータの何分の1かの大きさで済みます。

索引は、指定したキー値を含む表の行へのポインタを保有します。通常の索引には、そのキー値がある行に対応する各キーのROWIDのリストが格納されます。ビットマップ索引では、各キー値のビットマップが、ROWIDのリストのかわりに使用されます。

ビットマップの各ビットは、ROWIDに対応します。ビットが設定されると、対応するROWIDを持つ行に、キー値が含まれることを意味します。マッピング機能によってビットの位置が実際のROWIDに変換されるため、ビットマップ索引は、通常の索引と同じ機能を提供します。ビットマップ索引は、ビットマップを圧縮して格納します。個別キー値の数が少ない場合は、ビットマップ索引の圧縮率が高くなり、Bツリー索引に対する領域節約の面での優位性がさらに高くなります。

ビットマップ索引は、WHERE句に複数の条件が含まれる問合せに対して最も効率的です。すべての条件ではなく一部の条件のみを満たす行は、表自体がアクセスされる前に除外されます。これによって、応答時間が大幅に削減されます。どの索引を作成するべきか判断できない場合は、SQLアクセス・アドバイザを使用すると、作成するべき索引についてのリコメンデーションが生成されます。ビットマップ索引のビットマップは瞬時に結合されるので、通常は単一列のビットマップ索引を使用するのが最適です。

ビットマップ索引を作成するときは、NOLOGGINGおよびCOMPUTE STATISTICSを使用する必要があります。また、ビットマップ索引は、通常、メンテナンスを行うよりも削除して再作成するほうが簡単であることに注意してください。

ビットマップ索引およびNULLについて

ビットマップ索引は、他のほとんどのタイプの索引とは異なり、NULL値を持つ行を含みます。NULLの索引付けは、集計関数COUNTが指定されている問合せなどの、いくつかのタイプのSQL文に有効です。

例4-1 ビットマップ索引

SELECT COUNT(*) FROM customers WHERE cust_marital_status IS NULL;

この問合せでは、cust_marital_statusのビットマップ索引が使用されます。この問合せでは、Bツリー索引を使用できないことに注意してください。Bツリー索引にはNULL値は格納されないためです。

SELECT COUNT(*) FROM customers;

NULLデータを持つ行を含めて、表のすべての行に索引が付けられるため、すべてのビットマップ索引をこの問合せに使用できます。NULLに索引が付けられていない場合、オプティマイザは、NOT NULL制約が指定されている列にある索引のみを使用できます。

パーティション表のビットマップ索引について

ビットマップ索引をパーティション表に作成できますが、パーティション表に対してローカルである必要があり、グローバル索引にできません。パーティション表に作成できるグローバル索引は、パーティション化または非パーティション化のBツリー索引のみです。

関連項目:

  • 『Oracle Database SQL言語リファレンス』

  • 『Oracle Database VLDBおよびパーティショニング・ガイド』

データ・ウェアハウス・アプリケーションの索引に対するメリット

ビットマップ索引は、ユーザーがデータの更新ではなく、データの問合せを行うデータ・ウェアハウス・アプリケーションに使用します。この種の索引は、データを変更する同時トランザクションの数が多いOLTPアプリケーションには適していません。

索引は、カーディナリティが高い列のほうがメリットがあります。

パラレル問合せおよびパラレルDMLは、ビットマップ索引でも動作します。ビットマップ索引では、索引のパラレル作成、連結索引もサポートされます。

カーディナリティとビットマップ索引について

ビットマップ索引は、表の行数に対する個別値の数の比率が小さい列に対して最も効果的です。この比率は、カーディナリティ度と呼ばれます。性別の列は個別値が2つ(男性と女性)しかないため、ビットマップ索引に最適です。ただし、データ・ウェアハウス管理者は、カーディナリティが高い列にビットマップ索引を作成する場合もあります。

たとえば、行が100万ある表では、10,000の個別値を持つ列がビットマップ索引の候補になります。この列のビットマップ索引は、特に、この列が他の索引付けされた列と連結して頻繁に問い合せられる場合に、Bツリー索引よりパフォーマンスが高くなります。実際、典型的なデータ・ウェアハウス環境では、すべての非一意列がビットマップ索引の候補です。

Bツリー索引は、カーディナリティが高いデータ(customer_namephone_numberなど、固有な値を多く持つデータ)に対して最も効果的です。データ・ウェアハウスでは、Bツリー索引は、一意の列またはカーディナリティが非常に高い列(ほとんど一意である列)にのみ使用してください。データ・ウェアハウスの索引は、ほとんどがビットマップ索引であっても問題ありません。

非定型問合せなどを行う場合、ビットマップ索引によって問合せのパフォーマンスが大幅に向上します。結果のビットマップをROWIDに変換する前に、対応するブール操作をビットマップに対して直接実行することにより、問合せのWHERE句で指定したANDおよびOR条件は、すぐに解決されます。結果の行数が少ない場合は、全表スキャンを行うことなく、すぐに問合せの結果が戻されます。

次の問合せの出力は、ある会社のcustomers表の一部を示しています。

SELECT cust_id, cust_gender, cust_marital_status, cust_income_level
FROM customers;

CUST_ID    C CUST_MARITAL_STATUS  CUST_INCOME_LEVEL
---------- - -------------------- ---------------------
... 
        70 F                      D: 70,000 - 89,999
        80 F married              H: 150,000 - 169,999
        90 M single               H: 150,000 - 169,999
       100 F                      I: 170,000 - 189,999
       110 F married              C: 50,000 - 69,999
       120 M single               F: 110,000 - 129,999
       130 M                      J: 190,000 - 249,999
       140 M married              G: 130,000 - 149,999
...

cust_gendercust_marital_statusおよびcust_income_levelは、すべてカーディナリティが低い列(MARITAL_STATUSは3つの値のみ、GENDERは2つの値のみ、INCOME_LEVELは12の値のみが存在する列)であるため、これらの列にはビットマップ索引が理想的です。cust_idは一意の列であるため、この列にはビットマップ索引を作成しないでください。かわりに、この列に一意のBツリー索引を作成すると、最も効率的に表示および検索できます。

表4-1に、この例のcust_gender列に対するビットマップ索引を示します。この索引は、2つの別々のビットマップで構成されており、それぞれが性別に対応しています。

表4-1 ビットマップ索引の例

顧客ID gender='M' gender='F'

cust_id 70

0

1

cust_id 80

0

1

cust_id 90

1

0

cust_id 100

0

1

cust_id 110

0

1

cust_id 120

1

0

cust_id 130

1

0

cust_id 140

1

0

ビットマップの各エントリ(ビット)は、customers表の1つの行に対応します。各ビットの値は、表にある対応する行の値に依存します。たとえば、ビットマップcust_gender='F'には、最初のビットとして1が含まれています。これは、customers表の最初の行にある性別がFであるためです。ビットマップcust_gender='F'の第3ビットは0です。これは、3行目の性別がFでないためです。

会社の顧客の人口統計情報傾向を調査するアナリストが、「既婚者で、所得レベルがGまたはHの顧客がどれだけいるか」と質問するとします。この質問は、次の問合せで表すことができます。

SELECT COUNT(*) FROM customers
WHERE cust_marital_status = 'married' 
AND cust_income_level IN ('H: 150,000 - 169,999', 'G: 130,000 - 149,999');

図4-1に示すように、ビットマップ索引は、単にビットマップにある1の数をカウントすることで、この問合せを効率的に処理できます。結果セットはビットマップのORマージ操作を使用して検索され、ROWIDへの変換は不要です。さらに条件を満たす特定の顧客属性も確認するには、ビットマップからROWIDへの変換後に、結果ビットマップを使用して表にアクセスします。

図4-1 ビットマップ索引を使用した問合せの実行

図4-1の説明は図の下のリンクをクリックしてください。
「図4-1 ビットマップ索引を使用した問合せの実行」の説明

ビットマップ索引の使用対象の判定方法

ファクト表のみが問い合され、索引付けされた列に対する条件がある場合、またはファクト表が2つ以上のディメンション表と結合され、そのファクト表の外部キー列に対する索引があり、ディメンション表の列に対する条件がある場合に、ビットマップ索引は有効です。

次の条件が当てはまる場合、ファクト表の列はビットマップ索引の候補となります。

  • 索引付けされた列の各個別値に対し行が100以上ある。この制限が当てはまる場合、ビットマップ索引は通常の索引よりも大幅に小さくなり、通常の索引よりも早く作成できます。たとえば、数十億の行がある表に、100万の個別値が含まれる場合などです。

また、次のいずれかの場合も該当します。

  • 索引付けされた列が、問合せで制限される(WHERE句で参照される)。

または

  • 索引付けされた列が、ディメンション表の外部キーである。この場合、この索引によってスター型変換が行われる可能性が高くなります。

データ・ウェアハウスでのビットマップ結合索引の使用

単一表のビットマップ索引の他に、ビットマップ結合索引を作成できます。これは、複数の表の結合に対するビットマップ索引です。ビットマップ結合索引では、索引付けされる表のビットマップは、結合先の表の値のために作成されます。データ・ウェアハウス環境では、結合条件はディメンション表の主キー列とファクト表の外部キー列の間の内部等価結合です。

ビットマップ結合索引を使用すると、パフォーマンスを大幅に向上させることができます。結合結果を格納することで、ビットマップ結合索引を使用するSQL文では、結合をまったく行わずに済みます。また、ビットマップ結合索引では、結合列に対する通常のビットマップ索引と比較して、個別値の数がさらに少なくなることがほとんどなので、ビットマップの圧縮率が高くなります。その結果、結合列に対する通常のビットマップ索引よりも、使用する領域が小さくなります。

ビットマップ結合索引は、マテリアライズド結合ビューより格納の効率がはるかによく、事前に結合をマテリアライズする方法の代替手段です。これは、マテリアライズド結合ビューでは、ファクト表のROWIDが圧縮されないためです。

Bツリー索引とビットマップ索引では、最大列数の制限が異なります。

関連項目:

データ・ウェアハウスにおけるビットマップ結合索引の4つの結合モデル

ビットマップ結合索引は、スター・モデル環境で使用するのが最も一般的です。スター・モデル環境とは、大規模な表の索引列に、1つ以上の小規模な表が結合されている環境のことです。大規模な表のことをファクト表、小規模な表のことをディメンション表と呼びます。次の項では、ビットマップ結合索引でサポートされている4つの結合モデルについて説明します。

次の例は、1つのディメンション表の列と1つのファクト表を結合するビットマップ結合索引を示しています。ビットマップ索引をcustomers表のcust_gender列に作成したカーディナリティとビットマップ索引についての例とは異なり、ここでは、結合列customers(cust_gender)のビットマップ結合索引をファクト表salesに作成します。表salesは、次のようにcust_id値のみを格納します。

SELECT time_id, cust_id, amount_sold FROM sales;

TIME_ID   CUST_ID    AMOUNT_SOLD
--------- ---------- -----------
01-JAN-98      29700        2291
01-JAN-98       3380         114
01-JAN-98      67830         553
01-JAN-98     179330           0
01-JAN-98     127520         195
01-JAN-98      33030         280
...

このようなビットマップ結合索引を作成するには、列customers(cust_gender)を表salesに結合する必要があります。結合条件は、ビットマップ結合索引のCREATE文の一部として指定します。

CREATE BITMAP INDEX sales_cust_gender_bjix
ON sales(customers.cust_gender)
FROM sales, customers
WHERE sales.cust_id = customers.cust_id
LOCAL NOLOGGING COMPUTE STATISTICS;

次の問合せにより、ビットマップ結合索引に格納されるビットマップの作成に使用する結合結果が示されます。

SELECT sales.time_id, customers.cust_gender, sales.amount_sold
FROM sales, customers
WHERE sales.cust_id = customers.cust_id;

TIME_ID   C AMOUNT_SOLD
--------- - -----------
01-JAN-98 M        2291
01-JAN-98 F         114
01-JAN-98 M         553
01-JAN-98 M           0
01-JAN-98 M         195
01-JAN-98 M         280
01-JAN-98 M          32
...

表4-2に、この例におけるビットマップ結合索引のビットマップ表現を示します。

表4-2 ビットマップ結合索引の例

売上レコード cust_gender='M' cust_gender='F'

sales record 1

1

0

sales record 2

0

1

sales record 3

1

0

sales record 4

1

0

sales record 5

1

0

sales record 6

1

0

sales record 7

1

0

次の例のように、複数の列または複数の表を使用すると、他のビットマップ結合索引を作成できます。

例4-2 ビットマップ結合索引: 複数のディメンション列と1つのファクト表の結合

ビットマップ結合索引は、次の例のように、1つのディメンション表の複数の列に作成できます。次の例では、shスキーマのcustomers(cust_gender, cust_marital_status)を使用しています。

CREATE BITMAP INDEX sales_cust_gender_ms_bjix
ON sales(customers.cust_gender, customers.cust_marital_status)
FROM sales, customers
WHERE sales.cust_id = customers.cust_id
LOCAL NOLOGGING COMPUTE STATISTICS;

例4-3 ビットマップ結合索引: 複数のディメンション表と1つのファクト表の結合

ビットマップ結合索引は、次の例のように、複数のディメンション表に作成できます。次の例では、customers(gender)products(category)を使用しています。

CREATE BITMAP INDEX sales_c_gender_p_cat_bjix
ON sales(customers.cust_gender, products.prod_category)
FROM sales, customers, products
WHERE sales.cust_id = customers.cust_id
AND sales.prod_id = products.prod_id
LOCAL NOLOGGING COMPUTE STATISTICS;

例4-4 ビットマップ結合索引: スノーフレーク・スキーマ

複数の表のビットマップ結合索引を作成できます。この場合、索引付けされた列は、別の表を使用して索引付けされた表に結合されます。たとえば、countries表がsales表と直接結合されていなくても、countries.country_nameの索引を作成できます。かわりに、countries表がcustomers表に結合され、customers表はsales表に結合されます。このタイプのスキーマは、一般にスノーフレーク・スキーマと呼ばれます。

CREATE BITMAP INDEX sales_co_country_name_bjix
ON sales(countries.country_name)
FROM sales, customers, countries
WHERE sales.cust_id = customers.cust_id
  AND customers.country_id = countries.country_id
LOCAL NOLOGGING COMPUTE STATISTICS;

ビットマップ結合索引の制限事項と要件

結合結果を格納する必要があるため、ビットマップ結合索引には次の制限事項があります。

  • パラレルDMLはファクト表でのみサポートされます。ディメンション表に対してパラレルDMLを行うと、索引はUNUSABLEのマークが付けられます。

  • ビットマップ結合索引を使用する場合、異なるトランザクションで同時に更新できる表は1つのみです。

  • 結合に2回同じ表は使用できません。

  • 一時表にはビットマップ結合索引は作成できません。

  • 索引の列は、すべてディメンション表の列である必要があります。

  • ディメンション表の結合列は、主キー列であるか、一意制約を持つ必要があります。

  • ファクト表との結合に関与しているディメンション表の1つ以上の列は、主キー列であるか、一意制約を持つ必要があります。

  • ディメンション表に複合主キーがある場合、主キーの各列が結合の一部である必要があります。

  • 通常のビットマップ索引の作成に関する制限事項も、ビットマップ結合索引に適用されます。たとえば、UNIQUE属性を持つビットマップ索引は作成できません。その他の制限事項については、『Oracle Database SQL言語リファレンス』を参照してください。

データ・ウェアハウスでのBツリー索引の使用

Bツリー索引は、木をさかさまにしたような構造になっています。索引の最下位層レベルには、実際のデータ値および対応する行へのポインタがあります。これは、本の索引に、各索引エントリに対応するページ数があることとよく似ています。

一般に、典型的な問合せが索引付けされた列を参照して少数の行を取り出すことがわかっている場合に、Bツリー索引を使用します。これらの問合せでは、索引を参照する方が、行を迅速に検索できます。しかし、本の索引にたとえると、本のトピックを1つずつ参照する場合、そのトピックを索引で調べてから該当ページを検索することはありません。本のすべての章を読む方が速いことになります。これと同様に、表内のほとんどの行を取り出す場合、索引を参照して表の行を検索するのでは意味がありません。かわりに、表を読み込むかまたはスキャンします。

データ・ウェアハウスでは、一意キーの索引付けに最もよく使用されるのはBツリー索引です。多くの場合、データ・ウェアハウスにあるこれらの列に索引付けを行う必要はありません。これは、事前に実行されるETL処理の中で一意性はすでに確保されており、通常のデータ・ウェアハウスの問合せは、こうした索引を使用してもパフォーマンスが向上しないためです。Bツリー索引は、第3正規形のスキーマを使用する環境で使用するのが一般的です。ほとんどのデータ・ウェアハウス環境では、ビットマップ索引が、Bツリー索引よりもよく使用されます。

Bツリー索引とビットマップ索引では、最大列数の制限が異なります。これらの制限の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

索引の圧縮の使用

ビットマップ索引は常に、ユーザーの操作を必要とすることなく、独自の方法で圧縮されて格納されます。Bツリー索引は、明示的に圧縮して格納することで、領域を大幅に節約することが可能です。この際、各索引ブロックにはより多くのキーが格納され、I/Oの削減およびパフォーマンスの向上にもつながります。

キーの圧縮によって、Bツリー索引を圧縮できます。この結果、重複値による領域のオーバーヘッドが低減されます。非一意索引では、すべての索引列を圧縮形式で格納できますが、一意索引では、少なくとも1つの索引列は圧縮せずに格納する必要があります。キーの圧縮機能に加え、OLTPの索引圧縮機能はより高い圧縮度を提供しますが、データ・ウェアハウス環境よりもOLTPアプリケーションに適しています。

通常、索引のキーは、グループ化要素と一意要素という2つの要素を持っています。一意要素を持つようにキーが定義されていない場合は、ROWIDをグループ化要素に追加する形で一意要素が提供されます。キーの圧縮では、グループ化要素が分離され、複数の一意要素が共有できるような形で格納されます。圧縮対象として選択された列のカーディナリティによって、実現可能な圧縮率が決まります。したがって、たとえば5つの列からなる一意索引の一意性のほとんどが、後ろの2列によって実現されている場合は、先頭の3列を圧縮して格納するのが最も効率的ということになります。4つの列を圧縮する場合は、重複性はほとんど失われ、圧縮率が低下します。

キーの圧縮によって、索引の領域要件は低くなりますが、索引スキャン時のキー列値の再構築に必要なCPUタイムが長くなる場合があります。また、接頭辞エントリごとに4バイトのオーバーヘッドが生じるので、追加の領域オーバーヘッドも発生します。

関連項目:

  • キーの圧縮の詳細は、『Oracle Database管理者ガイド』を参照してください。

  • OLTP索引の圧縮の詳細は、『Oracle Database管理者ガイド』を参照してください。

ローカル索引とグローバル索引の選択基準

パーティション表のBツリー索引は、ローカルまたはグローバルにできます。Oracle8i以前のリリースでは、データ・ウェアハウス環境ではグローバル索引を使用しないようにお薦めしていました。これは、パーティションのDDL文(ALTER TABLE ... DROP PARTITIONなど)により索引全体が無効になり、索引の再構築に手間がかかったためです。グローバル索引は、DDLの後に使用不可とマークされなくてもメンテナンス可能です。これにより、データ・ウェアハウス環境におけるグローバル索引の効率が向上しています。

ただし、ローカル索引の方がグローバル索引より一般的です。グローバル索引を使用する必要があるのは、ローカル索引では満たせない特定の要件(非パーティション化キーの一意索引や、パフォーマンス要件など)がある場合です。

パーティション表のビットマップ索引は、常にローカルです。

データ・ウェアハウスでの整合性制約の使用方法

整合性制約は、データが、データベース管理者によって指定されたガイドラインに従うことを保証するためのメカニズムです。

最も一般的なタイプの制約は、次のとおりです。

  • UNIQUE制約

    特定の列が一意であることを保証します。

  • NOT NULL制約

    NULL値が許されないことを保証します。

  • FOREIGN KEY制約

    2つのキーが主キーと外部キーの関係を共有することを保証します。

制約は、データ・ウェアハウスにおいて、次の目的に使用できます。

  • データの正当性

    制約により、不適切なデータの挿入を防止するために、データ・ウェアハウスのデータがデータ整合性および正確さのガイドラインに従っているかどうかが検証されます。

  • 問合せの最適化

    Oracle Databaseでは、SQL問合せを最適化するときに、制約が使用されます。制約は、問合せの最適化に多くの点で効果的ですが、マテリアライズド・ビューのクエリー・リライトに特に重要です。

多くのリレーショナル・データベース環境とは異なり、データ・ウェアハウスのデータは通常、抽出、変換、ロード(ETL)プロセス中の、制御された状況下で追加または変更されます。通常、OLTPシステムとは異なり、複数のユーザーがデータ・ウェアハウスを直接更新することはありません。

この項には次のトピックが含まれます:

制約の状態の概要

データ・ウェアハウスにおいて最適な制約の使用方法を理解するには、まず、制約の基本的な目的を理解する必要があります。

このような目的をいくつか次に示します。

  • 施行

    制約を施行するには、制約がENABLE状態である必要があります。ENABLE状態の制約により、任意の1つ(または複数)の表におけるすべてのデータの変更が、制約の条件を満たすことが保証されます。データ変更操作によってデータが制約に違反する場合、その操作は制約違反エラーとなり正常に実行されません。

  • 妥当性チェック

    妥当性チェックを行うために制約を使用するには、制約がVALIDATE状態である必要があります。制約がVALIDATED状態の場合、表に現在存在しているすべてのデータが制約を満たします。

    妥当性チェックは、施行とは関係ありません。業務系システムでの一般的な制約はENABLEDおよびVALIDATED状態ですが、VALIDATED状態であってもENABLED状態でないか、またはその逆(ENABLED状態であってもVALIDATED状態でない)の場合もあります。後者の2つの状態は、データ・ウェアハウスで効果的です。

  • 信頼

    特定の制約の条件がTRUEであることがわかっているため、妥当性チェックや制約の施行を必要としない場合があります。しかしそのような場合でも、問合せの最適化やパフォーマンスの改善のために、制約を存在させることができます。この目的で使用する制約は、信頼またはRELY制約と呼ばれ、RELY状態である必要があります。RELY状態は、指定された制約がTRUEであることを信頼してよいことをOracleに通知するメカニズムを提供します。

    RELY状態の影響を受けるのは、VALIDATED状態でない制約のみであることに注意してください。

一般的なデータ・ウェアハウスの整合性制約

この項では、読者が制約の一般的な使用方法を理解していることを前提としています。つまり、ENABLEかつVALIDATEDな状態の制約です。データ・ウェアハウスでは、このような制約の作成およびメンテナンスに非常にコストがかかるため、多くのユーザーにとって、このような制約が効率的でないことは明らかです。この項の内容は次のとおりです。

データ・ウェアハウスでの一意制約

一意制約は、通常、一意索引を使用して規定されます。ただし、表が非常に大規模になる可能性があるデータ・ウェアハウスでは、一意索引を作成すると、処理時間およびディスク領域の点で非常にコストがかかる場合があります。

データ・ウェアハウスにsales表があり、その表にsales_id列が含まれているとします。sales_idは、単一の売上トランザクションを一意に識別し、データ・ウェアハウス管理者は、この列がデータ・ウェアハウス内で一意であることを保証する必要があります。

制約を作成する方法の1つを、次に示します。

ALTER TABLE sales ADD CONSTRAINT sales_uk
UNIQUE (prod_id, cust_id, promo_id, channel_id, time_id);

デフォルトでは、この制約はENABLEかつVALIDATEDな状態です。Oracleは、この制約をサポートするために、sales_idに一意索引を暗黙的に作成します。ただし、次の3つの理由から、この索引がデータ・ウェアハウスでは不適切な場合があります。

  • sales表には数百万または数十億もの行が含まれることが多いため、一意索引は非常に大きくなる可能性があります。

  • 一意索引は、問合せの実行にはあまり使用されません。ほとんどのデータ・ウェアハウスの問合せは一意キーについての条件検索を行わないため、この索引を作成してもパフォーマンスが改善される可能性はあまりありません。

  • salessales_id以外の列でパーティション化されている場合は、一意索引はグローバル索引である必要があります。これによって、sales表でのすべてのメンテナンス操作が悪影響を受ける場合があります。

一意索引は、sales表で変更された個々の行が一意制約を満たすことを保証するために必要です。

データ・ウェアハウス表の場合に使用できる、一意制約にかわる方法を次の文に示します。

ALTER TABLE sales ADD CONSTRAINT sales_uk
UNIQUE (prod_id, cust_id, promo_id, channel_id, time_id) DISABLE VALIDATE;

この文によって一意キー制約が作成されますが、制約がDISABLED状態であるため、一意索引は必要ありません。この方法によって、制約が一意索引のデメリットの影響を受けずに一意性を保証できるため、多くのデータ・ウェアハウス環境でメリットがあります。

ただし、データ・ウェアハウス管理者が、DISABLE VALIDATE制約を考慮する場合にトレードオフがあります。この制約はDISABLED状態であるため、一意の列を変更するDML文はsales表に対して実行できません。制約が存在する状態でこの表を変更するには、次の2つの方法があります。

  • DDLを使用して、この表にデータを追加します(パーティションの交換など)。マテリアライズド・ビューのリフレッシュの例を参照してください。

  • この表を変更する前に、制約を削除します。その後、すべての必要なデータ修正を行います。最後に、DISABLED状態の制約を再作成します。この制約を再作成する方が、ENABLED状態の制約を再作成するより効率的です。ただし、この方法では、制約の削除中にsales表に追加されたデータが一意であることは保証されません。

データ・ウェアハウスでの外部キー制約

スター・スキーマ・データ・ウェアハウスでは、外部キー制約により、ファクト表とディメンション表のリレーションシップの妥当性がチェックされます。制約の例を次に示します。

ALTER TABLE sales ADD CONSTRAINT sales_time_fk
FOREIGN KEY (time_id) REFERENCES times (time_id)
ENABLE VALIDATE;

ただし、場合によっては、外部キー制約に異なる状態(特に、ENABLE NOVALIDATE状態)を使用するように選択することがあります。データ・ウェアハウス管理者は、次のいずれかの場合に、ENABLE NOVALIDATE制約を使用することがあります。

  • 制約を満たさないデータが表にあるが、データ・ウェアハウス管理者が規定する制約を作成する場合

  • 施行済の制約がすぐに必要な場合

データ・ウェアハウスで、新しいデータはファクト表に毎日ロードされ、ディメンション表は週末にのみリフレッシュされるとします。その週の間は、ディメンション表とファクト表が実際には外部キー制約を満たさない可能性があります。それでも、データ・ウェアハウス管理者は、ETLプロセス外で外部キー制約に影響する可能性がある変更が行われないようにするため、この制約を施行する場合があります。つまり、次のように、ETLプロセスの実行後に外部キー制約を毎晩作成できます。

ALTER TABLE sales ADD CONSTRAINT sales_time_fk
FOREIGN KEY (time_id) REFERENCES times (time_id)
ENABLE NOVALIDATE;

ENABLE NOVALIDATEを使用すると、制約がTRUEであると考えられる場合にも、施行される制約をすばやく作成できます。ETLプロセスによって、外部キー制約がTRUEであるかどうかが検証されるとします。データベースにこの外部キー制約を再検証させるには時間およびデータベース・リソースが必要となるため、かわりに、データ・ウェアハウス管理者は、ENABLE NOVALIDATEを使用して外部キー制約を作成できます。

データ・ウェアハウスでのRELY制約

ETLプロセスでは、通常、ある制約がTRUEかどうかが検証されます。たとえば、ファクト表の受信データにあるすべての外部キーの妥当性チェックを実行します。これは、データ・ウェアハウスに制約を実装するかわりに、制約に従ったデータが提供されることが信頼できることを意味します。RELY制約を次のように作成します。

ALTER TABLE sales ADD CONSTRAINT sales_time_fk
FOREIGN KEY (time_id) REFERENCES times (time_id) 
RELY DISABLE NOVALIDATE;

この文は、主キーがRELY状態であることを前提としています。RELY制約は、データの妥当性チェックに使用されない場合にも、次のことができます。

RELY制約の作成には、コストがほとんどかかりません。また、DML中やロード中にもオーバーヘッドは発生しません。制約がVALIDATED状態ではないため、その作成に必要なデータ処理はありません。

データ・ウェアハウスでのNOT NULL制約

クエリー・リライトを使用する際は、NOT NULL制約が必要かどうかを考慮する必要があります。それらが必要となる典型例は、後戻り結合クエリー・リライトを使用する場合です。

関連項目:

データ・ウェアハウスでの整合性制約とパラレル化

すべての制約は、パラレルで妥当性チェックできます。非常に大規模な表で制約の妥当性チェックを行う場合、パフォーマンスの目標を達成するために、パラレル化が必要になります。ある任意の制約操作の並列度は、基礎となる表のデフォルトの並列度によって決定されます。

データ・ウェアハウスでの整合性制約とパーティション化

データをパーティション化する前に、制約を作成してメンテナンスできます。データ・ウェアハウスにおけるパーティション化の重要性については、以降の章を参照してください。パーティション化により、他の多くの操作の管理と同様に、制約管理も改善できます。たとえば、マテリアライズド・ビューのリフレッシュには、別々のステージング表にUNIQUEおよびFOREIGN KEYの各制約を作成する例があります。これらの制約はEXCHANGE PARTITION文の実行中にメンテナンスされます。

データ・ウェアハウスでのビューの制約

ビューの制約を作成できます。ビューでサポートされるタイプの制約は、RELY制約のみです。

このタイプの制約は、問合せが実表ではなくビューにアクセスする際に、データベース管理者が、ビューとの間のリレーションシップを定義する必要がある場合に有効です。

データ・ウェアハウスにおけるパラレル実行について

今日のデータベースには、それがウェアハウスや運用データ・ストア、またはOLTPシステムのどれであるかに限らず、大量の情報が格納されています。しかし、含まれるデータの量が膨大であるため、正しい情報をタイムリーに検索し、提示することは容易ではありません。

パラレル実行は、この課題に対処するための機能です。パラレル実行(パラレル化とも呼ばれます)では、複数のプロセスを使用して単一のタスクを完了させることで、テラバイトのデータを数時間や数日ではなく、数分で処理できます。これにより、通常意思決定支援システム(DSS)およびデータ・ウェアハウスに関連付けられているサイズの大きなデータベース上で、データ集中型の操作のレスポンス時間を大幅に削減できます。また、OLTPシステム上で、索引の作成などのバッチ処理またはスキーマ・メンテナンス操作のためにパラレル実行を実装することもできます。パラレル化の概念は、タスクへの分解であり、これにより1つのプロセスで問合せに関するすべての処理を実行するのではなく、多くのプロセスが同時に各処理を実行します。たとえば、1年の合計売上げを4つのプロセスで計算するのに、1つのプロセスですべての四半期を処理するのではなく、各プロセスが1年の四半期それぞれを処理する場合です。これを使用するとパフォーマンスの大幅な向上が見込めます。

パラレル実行では、次のプロセスのパフォーマンスを向上できます。

  • 大規模な表のスキャン、結合またはパーティション索引スキャンを必要とする問合せ

  • 大規模な索引の作成

  • 大規模な表の作成(マテリアライズド・ビューを含む)

  • バルク挿入、更新、マージ、削除

また、パラレル実行を使用して、Oracleデータベース内のオブジェクト型にアクセスできます。たとえば、パラレル実行を使用してラージ・オブジェクト(LOB)にアクセスできます。

大規模なデータ・ウェアハウスでは、優れたパフォーマンスを得るために、常にパラレル実行を使用する必要があります。OLTPアプリケーションの特定の処理(バッチ処理など)も、パラレル実行を行うことでパフォーマンスが大幅に向上します。

この項には次のトピックが含まれます:

パラレル実行を使用する理由

通りにある車の台数を数えるというタスクがあるとします。このタスクを実行するには2つの方法があります。1つは、自分が通りまで行き、車の台数を数えます。もう1つは、友人に協力してもらい、それぞれ通りの反対側から車の台数を数え始め、2人が落ち合ったところでそれぞれの台数を足します。

友人が車を数える速さがあなたと同じだとした場合、通りにあるすべての車を数えるタスクは、自分一人で行う場合と比べて半分の時間で終えることができます。このような場合、処理は直線的に測定できます。つまりリソースの数を2倍にすると、全体の処理時間は半分になります。

データベースの場合も、車を数える例とさほど変わりません。リソースの数を2倍にすることで、処理時間が最初の半分になれば、その処理は直線的に測定できます。直線的に測定できることが、車を数える場合でも、データベース問合せからの応答を配信する場合でも、パラレル処理の最終的な目標です。

関連項目:

  • パラレル実行の使用に関する詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

次のトピックでは、パラレル実行が役立つシナリオについて説明します。

パラレル実行を実装する場合

パラレル実行は、次のすべての特性を持つシステム上で有効です。

  • 対称型マルチプロセッサ(SMP)、クラスタ、または大規模なパラレル・システム

  • 十分なI/Oバンド幅

  • 稼働中でないCPUまたは断続的に使用されているCPU(CPUの使用率が通常30%未満のシステムなど)

  • ソート、ハッシュおよびI/Oバッファなどの追加のメモリー集中処理をサポートする十分なメモリー

システムでこれらの特徴が1つでも欠けていると、パラレル実行を使用してもパフォーマンスが大幅には改善されないことがあります。実際に、使用率の高すぎるシステムまたはI/O帯域幅が小さいシステムでは、パラレル実行によりシステム・パフォーマンスが低下する場合もあります。

パラレル実行のメリットは、DSSおよびデータ・ウェアハウス環境でわかります。OLTPシステムでも、バッチ処理やスキーマ・メンテナンス操作(索引の作成など)の際にはパラレル実行の利点が得られます。平均的で単純なDMLやSELECT文は、少数のレコードや単一のレコードに対してアクセスまたは操作し、OLTPアプリケーションを特徴付けますが、パラレルで実行するメリットはありません。

パラレル実行を実装しない場合

パラレル実行は、次の場合では通常有効ではありません。

  • 標準的な問合せまたはトランザクションが非常に短い(数秒またはそれ以下)環境。これには、ほとんどのオンライン・トランザクション・システムが含まれます。パラレル実行はこのような環境では役立ちません。パラレル実行サーバーの調整に関連するコストが発生するためです。短時間のトランザクションの場合、この調整のコストが並列処理のメリットを上回ります。

  • CPU、パラレル実行でもメモリーまたはI/Oリソースが大量に使用されている環境。パラレル実行は追加の使用可能なハードウェア・リソースを利用するように設計されています。そのようなリソースが使用できない場合、パラレル実行はなんのメリットももたらさず、パフォーマンスに悪影響をおよぼす可能性があります。

自動並列度および文のキューイング

名前が示すとおり、自動並列度では、オプティマイザにより決定された、CPU、I/Oおよびメモリーのリソース消費などの実行コストに基づき、Oracle Databaseが文(DML、DDLおよび問合せ)を実行する並列度(DOP)を決定します。つまり、データベースが問合せを解析し、コストを計算してから、実行に使用するDOPを決定します。コストの最も低い計画がシリアルに実行される可能性もオプションの1つとしてあります。図4-2に、この意思決定プロセスを示します。

図4-2 オプティマイザの計算: シリアルかパラレルか

図4-2の説明は図の下のリンクをクリックしてください。
「図4-2 オプティマイザの計算: シリアルかパラレルか」の説明

自動DOPの使用を選択する場合、特にしきい値が比較的低い場合は、多くの文がパラレルに実行している可能性があります。この場合の低いというのはシステムに対する相対的なものであり、絶対的な数量ではありません。

自動DOPを使用して多くの文がパラレルに実行しているという動作が予想されるため、使用可能なパラレル・プロセスの使用量を管理することはより重要になります。つまり、システムは、文をいつ実行するかについてインテリジェントであり、要求されたパラレル・プロセスの数が使用可能かどうかを検証する必要があります。この要求されたプロセスの数というのが、その文のDOPです。

このワークロード管理上の課題への答は、データベース・リソース・マネージャを使用した文のパラレル・キューイングです。文のパラレル・キューイングでは、文が要求したDOPが使用可能な場合に文が実行されます。たとえば、文が64のDOPを要求したときに、この顧客への支援に現在使用できるのが32プロセスのみである場合は、この文はキューに入れられます。

データベース・リソース・マネージャを使用すると、文を消費者グループを介してワークロードに分類できます。各消費者グループには適切な優先度およびパラレル・プロセスの適切なレベルが与えられます。また、各消費者グループはシステム・ロードに基づきパラレル文を格納する固有のキューを持ちます。

関連項目:

  • パラレル実行での自動DOPの使用の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

  • データベース・リソース・マネージャの使用の詳細は、『Oracle Database管理者ガイド』を参照してください。

データ・ウェアハウスにおけるインメモリー・パラレル実行について

従来、ほとんどの操作に対するパラレル処理では、データベース・バッファ・キャッシュがバイパスされ、ディスクから(ダイレクト・パスI/O経由で)パラレル実行サーバーのプライベート作業領域に直接読み込まれていました。DB_CACHE_SIZEの約2%よりも小さいオブジェクトのみがインスタンスのデータベース・バッファ・キャッシュに入れられますが、パラレルにアクセスされるオブジェクトはこの制限よりも大きいものがほとんどです。つまりこの動作は、そのプライベート処理以外では、使用可能なメモリが利用されることがほとんどないことを示します。しかし、この10年で、ハードウェア・システムはきわめて劇的に進化し、一般的なデータベース・サーバーのメモリ容量は2桁または3桁のギガバイトの領域に達しています。このことが、Oracleの圧縮技術と、Oracle Real Application Clustersの集計されたデータベース・バッファ・キャッシュを利用するOracle Databaseの機能とともに、テラバイトの領域でのオブジェクトのキャッシュを可能にしました。

インメモリー・パラレル実行は、この大きな集計されたデータベース・バッファ・キャッシュを利用します。バッファ・キャッシュを使用してオブジェクトにアクセスするパラレル実行サーバーを持つことにより、大量データのインメモリー・パラレル処理が最大限可能になり、大幅なパフォーマンスの向上が実現されます。

インメモリー・パラレル実行を使用して、SQL文がパラレルに発行されるとき、チェックが実行されて、文がアクセスするオブジェクトをシステムの集計されたバッファ・キャッシュに入れる必要があるかどうかが決定されます。この状況で、オブジェクトは表、索引またはパーティション・オブジェクトの場合には1つまたは複数のパーティションのいずれかです。

関連項目:

  • インメモリー・パラレル実行の使用方法の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

データ・ウェアハウスにおける記憶域要件の最適化について

データベース・ブロック内の重複値を排除してアーカイブされたデータを圧縮することにより、記憶域要件を削減できます。データ・ウェアハウスの記憶域を改善するためのデータ圧縮の使用では、圧縮データの使用方法について説明します。

圧縮可能なデータベース・オブジェクトには、表およびマテリアライズド・ビューが含まれます。パーティション表については、一部またはすべてのパーティションを圧縮できます。圧縮属性は、表領域、表または表のパーティションに対して宣言できます。表領域レベルで宣言された場合、その表領域で作成されたすべての表はデフォルトで圧縮されます。表(またはパーティションまたは表領域)の圧縮属性は変更可能で、その変更はその表に移動する新規データのみに適用されます。この結果、単一の表またはパーティションにはいくつかの圧縮されたブロックといくつかの通常のブロックが含まれます。これにより、圧縮後もデータのサイズが増加しないことが保証されます。圧縮によってブロックのサイズが増加する場合は、圧縮はそのブロックには適用されません。

データ・ウェアハウスの記憶域を改善するためのデータ圧縮の使用

いくつかのパーティションを圧縮するか、またはパーティション化されたヒープ構成表を作成できます。これを実行するには、完全なパーティション化された表を圧縮対象の表として定義するか、またはパーティション・レベルごとに定義するか、いずれかの定義を行います。特定の宣言のないパーティションは表定義から属性を継承し、表レベルの指定がない場合は表領域定義から継承します。

パーティションを圧縮するかまたは未圧縮のままにするかについての決定は、パーティション化されていない表と同じルールに従います。データを論理的に個別パーティションに区切る場合はレンジ・パーティション化とコンポジット・パーティション化を使用できるので、パーティション表は、主に読取り専用のデータ(パーティション)の圧縮部分として適切な候補です。たとえばこれは、古いデータが使用不可になる前の中間の段階としてのすべてのローリング・ウィンドウ操作に役立ちます。データを圧縮することにより、より多くの古いデータをオンラインで保持でき、追加的な記憶域使用の負荷を最小化できます。

また、既存の未圧縮の表パーティションを後で変更したり、新規の圧縮パーティションおよび未圧縮パーティションを追加したり、MERGE PARTITIONSPLIT PARTITIONまたはMOVE PARTITIONなどのデータ移動が必要なパーティション・メンテナンス操作の一部として圧縮属性を変更できます。パーティションにはデータを含めることができ、または空にすることもできます。

部分的または完全に圧縮されたパーティション表のアクセスおよびメンテナンスは、まったく圧縮されていないパーティション表の場合と同じです。また、完全に未圧縮のパーティション表に適用されたすべてのルールも、一部または完全に圧縮されたパーティション表に対して有効です。

データ圧縮を使用する手順

次の例では、1つの圧縮パーティション、costs_oldを使用してレンジ・パーティション化された表を作成します。表およびその他すべてのパーティションの圧縮属性は、表領域レベルから継承されます。

CREATE TABLE costs_demo (
   prod_id     NUMBER(6),    time_id     DATE, 
   unit_cost   NUMBER(10,2), unit_price  NUMBER(10,2))
PARTITION BY RANGE (time_id)
   (PARTITION costs_old 
       VALUES LESS THAN (TO_DATE('01-JAN-2003', 'DD-MON-YYYY')) COMPRESS,
    PARTITION costs_q1_2003 
       VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')),
    PARTITION costs_q2_2003
       VALUES LESS THAN (TO_DATE('01-JUN-2003', 'DD-MON-YYYY')),
    PARTITION costs_recent VALUES LESS THAN (MAXVALUE));

スター・クエリーおよび3NFスキーマの最適化

Oracleデータ・ウェアハウスは、スター・スキーマおよび第3正規形のスキーマでの適切な動作が可能です。この項では、両方のタイプのスキ-マでのパフォーマンスを最適化する重要な手法について説明します。スター・スキーマおよび3NFスキーマの概念上の背景については、第3正規形のスキーマについておよびスター・スキーマについてを参照してください。

スター・クエリーを使用する場合は、次の点を考慮する必要があります。

スター・クエリーの最適化

スター・クエリーは、ファクト表といくつかのディメンション表を結合するものです。各ディメンション表は、主キーから外部キーへの結合を使用してファクト表に結合されますが、ディメンション表同士は結合されません。オプティマイザによってスター・クエリーが認識されると、スター・クエリーのための効率的な実行計画が生成されます。スター・クエリーのチューニングでは、スター・クエリーのパフォーマンスを向上させる方法について説明します。

スター・クエリーのチューニング

スター・クエリーのパフォーマンスを最大限に向上させるためには、次の基本的なガイドラインに従う必要があります。

  • ビットマップ索引をファクト表の各外部キー列上に作成する必要があります。

  • 初期化パラメータSTAR_TRANSFORMATION_ENABLEDTRUEに設定する必要があります。これにより、スター・クエリーのための重要なオプティマイザ機能が使用可能になります。この機能は、下位互換性のためにデフォルトでFALSEに設定されています。

データ・ウェアハウスがこれらの条件を満たす場合、そのデータ・ウェアハウスで実行しているほとんどのスター・クエリーは、スター型変換と呼ばれる問合せ実行計画を使用します。スター型変換によって、スター・クエリーの問合せパフォーマンスが向上します。

スター型変換の使用

スター型変換は、元のスター・クエリーのSQLを暗黙的にリライト(または変換)することによる、強力な最適化テクニックです。エンド・ユーザーがスター型変換の詳細を知る必要はありません。Oracle Databaseの問合せオプティマイザでは、該当する場合にスター型変換が自動的に選択されます。

スター型変換は、スター・クエリーを効率的に実行することを目的とした問合せ変換です。Oracle Databaseでは、2つの基本フェーズを使用してスター・クエリーが処理されます。第1フェーズでは、ファクト表から必要な行(結果セット)のみを取り出します。この取出しにはビットマップ索引が使用されるため、非常に効率的です。第2フェーズでは、この結果セットをディメンション表に結合します。たとえば、「西部および南西部販売地域における過去3四半期の食料品部門の売上および利益はどうであったか」というエンド・ユーザーの問合せがあるとします。これは、1つの単純なスター・クエリーです。

この項には次のトピックが含まれます:

ビットマップ索引を使用したスター型変換

スター型変換の前提条件は、ファクト表の各結合列に単一列のビットマップ索引が存在することです。これらの結合列には、すべての外部キー列が含まれます。

たとえば、shサンプル・スキーマのsales表の場合、time_id列、channel_id列、cust_id列、prod_id列およびpromo_id列にビットマップ索引が定義されています。

次のスター・クエリーを考えてみます。

SELECT ch.channel_class, c.cust_city, t.calendar_quarter_desc,
   SUM(s.amount_sold) sales_amount
FROM sales s, times t, customers c, channels ch
WHERE s.time_id = t.time_id
AND   s.cust_id = c.cust_id
AND   s.channel_id = ch.channel_id
AND   c.cust_state_province = 'CA'
AND   ch.channel_desc in ('Internet','Catalog')
AND   t.calendar_quarter_desc IN ('1999-Q1','1999-Q2')
GROUP BY ch.channel_class, c.cust_city, t.calendar_quarter_desc;

この問合せは、2つのフェーズで処理されます。第1フェーズでは、Oracle Databaseは、ファクト表の外部キー列上のビットマップ索引を使用して、ファクト表から必要な行のみを識別し、取り出します。つまり、Oracle Databaseは、主に次の問合せを使用して、ファクト表から結果セットを取り出します。

SELECT ... FROM sales
WHERE time_id IN
  (SELECT time_id FROM times 
   WHERE calendar_quarter_desc IN('1999-Q1','1999-Q2'))
   AND cust_id IN
  (SELECT cust_id FROM customers WHERE cust_state_province='CA')
   AND channel_id IN
  (SELECT channel_id FROM channels WHERE channel_desc IN('Internet','Catalog'));

元のスター・クエリーがこの副問合せ表現に変換されたことから、これがアルゴリズムの変換ステップになります。ファクト表にアクセスするこの方法は、ビットマップ索引の効果を高めます。ビットマップ索引は、リレーショナル・データベース内に集合ベースの処理方法を提供します。Oracleでは、AND(標準的な集合についての用語で共通部分の意味)、OR(集合の用語で和集合)、MINUSCOUNTなどの集合演算を実行するための非常に高速な方法が実装されています。

このスター・クエリーでは、time_idのビットマップ索引を使用して、1999年第1四半期(1999-Q1)の売上(sales)に対応するファクト表のすべての行集合が識別されます。この集合は、ビットマップ(ファクト表のどの行がこの集合のメンバーであるかを示す1および0(ゼロ)の文字列)として表されます。

同様のビットマップが、1999年第2四半期(1999-Q2)の売上に対応するファクト表の行に取り出されます。ビットマップOR演算を使用して、このQ1の売上集合をQ2の売上集合と組み合せます。

追加の集合演算が、customerディメンションおよびproductディメンションに対して実行されます。この時点で、スター・クエリー処理には3つのビットマップがあります。各ビットマップは、別々のディメンション表に対応し、それぞれ、個々のディメンションの絞込み条件を満たすファクト表の行集合を表します。

これらの3つのビットマップは、ビットマップAND演算を使用して単一ビットマップに結合されます。この最後のビットマップは、ファクト表のうちディメンション表上の絞込み条件をすべて満たす行集合を表します。これは結果セットであり、問合せの評価に必要なファクト表からの正確な行集合です。ここまでのところでは、ファクト表の実際のデータには、まだアクセスしていないことに注意してください。これらの演算はすべて、ビットマップ索引とディメンション表のみを基にしています。ビットマップ索引はデータを圧縮した形で表すため、ビットマップの集合ベース演算は非常に効率的です。

結果セットが識別されると、ビットマップはSALES表から実データへのアクセスに使用されます。エンド・ユーザーの問合せに必要な行のみが、ファクト表から取り出されます。この時点で、すべてのディメンション表が、ビットマップ索引を使用してファクト表に効率的に結合されています。Oracle Databaseでは、各ディメンション表をファクト表に個別に結合するのではなく、すべてのディメンション表を単一の論理結合演算でファクト表に結合しているため、この技法を使用すると優れたパフォーマンスが得られます。

この問合せの第2フェーズでは、ファクト表の行(結果セット)をディメンション表に結合します。Oracleは、最も効率的な方法を使用して、ディメンション表にアクセスおよび結合します。ほとんどのディメンションは非常に小規模なため、これらのディメンション表への最も効率的なアクセス方法は、通常、表スキャンです。大規模なディメンション表については、表スキャンは最も効率的なアクセス方法ではない場合があります。前述の例では、product.departmentのビットマップ索引を使用して、食料品部門のすべての製品が高速で識別されます。Oracle Databaseでは、各ディメンション表のサイズおよびデータ分散に関するオプティマイザの知識に基づいて、オプティマイザが、特定のディメンション表に最適のアクセス方法を自動的に判断します。

同様に、各ディメンション表用の特定の結合方法(および索引付け方法)も、オプティマイザによってインテリジェントに判断されます。多くの場合、ディメンション表を結合するための最も効率的なアルゴリズムはハッシュ結合です。すべてのディメンション表が結合されると、最終結果がユーザーに戻されます。1つの表から一致する行のみを取り出してから、別の表に結合する問合せテクニックは、一般にセミ結合と呼ばれます。

ビットマップ索引を使用したスター型変換の実行計画

ビットマップ索引を使用したスター型変換から得られる典型的な実行計画は次のようになります。

SELECT STATEMENT
 SORT GROUP BY
  HASH JOIN
   TABLE ACCESS FULL                          CHANNELS
   HASH JOIN
    TABLE ACCESS FULL                         CUSTOMERS
    HASH JOIN
     TABLE ACCESS FULL                        TIMES
     PARTITION RANGE ITERATOR
      TABLE ACCESS BY LOCAL INDEX ROWID       SALES
       BITMAP CONVERSION TO ROWIDS
        BITMAP AND
         BITMAP MERGE
          BITMAP KEY ITERATION
           BUFFER SORT
            TABLE ACCESS FULL                 CUSTOMERS
           BITMAP INDEX RANGE SCAN            SALES_CUST_BIX
         BITMAP MERGE
          BITMAP KEY ITERATION
           BUFFER SORT
            TABLE ACCESS FULL                 CHANNELS
           BITMAP INDEX RANGE SCAN            SALES_CHANNEL_BIX
         BITMAP MERGE
          BITMAP KEY ITERATION
           BUFFER SORT
            TABLE ACCESS FULL                 TIMES
           BITMAP INDEX RANGE SCAN            SALES_TIME_BIX

この計画では、ファクト表は、ビットマップ・アクセス・パスを介してアクセスされます。このパスは、3つのマージされたビットマップのビットマップANDに基づきます。この3つのビットマップは、下位の行ソース・ツリーからビットマップが提供されているBITMAP MERGE行ソースによって生成されます。このような行ソース・ツリーはそれぞれ、副問合せ行ソース・ツリーの値をフェッチするBITMAP KEY ITERATION行ソースで構成されています。この例では、副問合せ行ソース・ツリーは、1つの全表アクセスです。これらの各値について、BITMAP KEY ITERATION行ソースがビットマップをビットマップ索引から取り出します。関係するファクト表の行は、このアクセス・パスを使用して取り出された後に、問合せ結果を生成するためにディメンション表および一時表と結合されます。

ビットマップ結合索引を使用したスター型変換

スター型変換において、ビットマップ索引の他にビットマップ結合索引も使用できます。次に示すような追加の索引構造があるとします。

CREATE BITMAP INDEX sales_c_state_bjix
ON sales(customers.cust_state_province)
FROM sales, customers
WHERE sales.cust_id = customers.cust_id
LOCAL NOLOGGING COMPUTE STATISTICS;

同じスター・クエリーでビットマップ結合索引を使用した場合の処理は、前述の例に似ています。唯一の違いは、単一表のビットマップ索引のかわりに、結合インデックスを使用してスター・クエリーの第1フェーズで顧客データにアクセスすることです。

ビットマップ結合索引を使用したスター型変換の実行計画

ビットマップ結合索引を使用したスター型変換の実行計画から得られる典型的な実行計画は次のようになります。

SELECT STATEMENT
 SORT GROUP BY
  HASH JOIN
   TABLE ACCESS FULL                          CHANNELS
   HASH JOIN
    TABLE ACCESS FULL                         CUSTOMERS
    HASH JOIN
     TABLE ACCESS FULL                        TIMES
     PARTITION RANGE ALL
      TABLE ACCESS BY LOCAL INDEX ROWID       SALES
       BITMAP CONVERSION TO ROWIDS
        BITMAP AND
         BITMAP INDEX SINGLE VALUE            SALES_C_STATE_BJIX
         BITMAP MERGE
          BITMAP KEY ITERATION
           BUFFER SORT
            TABLE ACCESS FULL                 CHANNELS
           BITMAP INDEX RANGE SCAN            SALES_CHANNEL_BIX
         BITMAP MERGE
          BITMAP KEY ITERATION
           BUFFER SORT
            TABLE ACCESS FULL                 TIMES
           BITMAP INDEX RANGE SCAN            SALES_TIME_BIX

この計画と前述の計画との唯一の違いは、customerディメンションのビットマップ索引スキャン内の選択のための処理がないことです。これは、customer.cust_state_provinceの結合述語情報を、ビットマップ結合索引sales_c_state_bjixで満たすことができるためです。

Oracleによるスター型変換の使用の選択

オプティマイザは、変換なしでも生成できる最適な計画を生成して保存します。変換が有効な場合、オプティマイザは問合せを変換し、必要に応じて、その変換された問合せを使用して最適な計画を生成します。オプティマイザは、この2つの問合せに対する最適な計画のコスト概算を比較して、変換または未変換のどちらの最適な計画を使用するかを決定します。

問合せがファクト表の行の大部分にアクセスする必要があるときは、変換ではなく、全表スキャンを使用する方がよい場合があります。ただし、ディメンション表について、選択による絞込み度合いが高く、ファクト表のわずかな部分のみを取り出す必要がある場合は、変換に基づく計画の方が適していることもあります。

オプティマイザは、多くの基準に基づいて適切であると判断した場合にのみ、ディメンション表に対して副問合せを生成します。副問合せは、すべてのディメンション表に対して生成されるわけではありません。また、オプティマイザが、表および問合せの性質に基づいて、問合せに変換を適用するメリットがないと判断することもあります。このような場合は、最適な通常の計画が使用されます。

スター型変換の制限

スター型変換は、次の特性が1つでもある表ではサポートされません。

  • ビットマップ・アクセス・パスと非互換の表ヒントがある問合せ。

  • ビットマップ索引が少なすぎる表。オプティマイザが副問合せを生成するためには、ファクト表の列にビットマップ索引がある必要があります。

  • リモート・ファクト表。ただし、リモート・ディメンション表は、生成された副問合せでは有効です。

  • アンチ結合された表。

  • 副問合せでディメンション表として使用済の表。

  • ビュー・パーティションではなく、実際はマージされていないビューである表。

  • ファクト表がマージされていないビューである表

  • パーティション・ビューがファクト表として使用されている表

次の場合には、オプティマイザではスター型変換が選択されないことがあります。

  • 効率的な単一表アクセス・パスを持つ表

  • 小さすぎて変換によるメリットがない表

さらに、次の条件下では、スター型変換で一時表は使用されません。

  • データベースが読取り専用モードの場合

  • スター・クエリーがシリアル化可能モードでのトランザクションの一部である場合

第3正規形スキーマの最適化

第3正規形(3NF)スキーマの最適化では、次の要件が必要です。

  • パワー

    パワーとは、ハードウェア構成のバランスがとれている必要があるということです。多くのデータ・ウェアハウス操作は、大規模な表スキャンおよび大量のランダムI/Oを実行する他のI/O集中型操作に基づいています。最適なパフォーマンスを達成するため、ハードウェア構成のサイズをエンド・ツー・エンドで設定して、このレベルのスループットを維持する必要があります。このタイプのハードウェア構成は、バランスのとれたシステムと呼ばれます。バランスのとれたシステムでは、CPUからディスクに至るまでのすべてのコンポーネントをまとめて編成して、利用可能な最大のI/Oスループットを保証します。

  • パーティション化

    大規模な表は、コンポジット・パーティション化(レンジ-ハッシュまたはリスト-ハッシュ)を使用してパーティション化する必要があります。これには次の3つの理由があります。

    • 数TBのデータの管理が容易

    • 必要なデータへのアクセシビリティの向上

    • 効果的でパフォーマンスの高い表の結合

    3NFスキーマ: パーティション化を参照してください。

  • パラレル実行

    パラレル実行により、データベース・タスクをパラレル化または小さい作業単位に分割できるため、複数のプロセスを同時に実行できます。パラレル化を使用すると、TB単位のデータを時間単位や日単位ではなく、数分以内でスキャンして処理できます。

    3NFスキーマ: パラレル問合せの実行を参照してください。

3NFスキーマ: パーティション化

パーティション化により、表、索引および索引構成表をより細かい単位に細分化できるようになります。データベース・オブジェクトの単位をパーティションと呼びます。各パーティションには独自の名前があり、独自の記憶特性を持つことができます。データベース管理者の視点からすると、パーティション・オブジェクトには、まとめて管理することも個別に管理することも可能な複数の単位があります。

このため、管理者は、パーティション・オブジェクトをかなり柔軟に管理できます。ただし、アプリケーションにとっては、パーティション表は非パーティション表と同じであるため、SQL DMLコマンドを使用してパーティション表にアクセスする際に変更は必要ありません。パーティション化によって、管理性、可用性およびパフォーマンスが向上し、多様なアプリケーションに大きなメリットがもたらされます。

管理性のためのパーティション化

レンジ・パーティション化により、大量のデータの管理性および可用性を向上できます。2年分の売上データまたは100TBが表に格納されている事例を検討します。1日の最後に、新しいバッチのデータを表にロードして、最も古い日のデータを削除する必要があります。売上表を日単位でレンジ・パーティション化する場合、パーティション交換ロードを使用して、新しいデータをロードできます。これは、エンド・ユーザー問合せにほとんど影響しない1秒以内の操作です。最も古い日付のデータの削除は、次のコマンドを発行するのみです。

SH@DBM1 > ALTER TABLE SALES DROP PARTITION Sales_Q4_2009;
簡易データ・アクセスのためのパーティション化

また、レンジ・パーティション化により、問合せに応答するための必要なデータのみスキャンすることを確認できます。ビジネス・ユーザーが週単位、たとえば、週ごとの売上合計などで売上データに主にアクセスすると想定する場合、日単位でこの表をレンジ・パーティション化すると、全体の表ではなく4つのパーティションのみをスキャンしてビジネス・ユーザーの問合せに応答するため、データに最も効率的な方法でアクセスできます。関係ないパーティションのスキャンを回避する機能は、パーティション・プルーニングと呼ばれます。

図4-3 パーティション・プルーニング

図4-3の説明は図の下のリンクをクリックしてください。
「図4-3 パーティション・プルーニング」の説明
結合パフォーマンスのパーティション化

パフォーマンスのため、ハッシュによるサブパーティション化を主に使用します。Oracleは、線形ハッシング・アルゴリズムを使用して、サブパーティションを作成します。ハッシュ・パーティション間でデータを確実に均等に分散するには、ハッシュ・パーティションの数を2の累乗(たとえば、2、4、8など)にすることを強くお薦めします。各ハッシュ・パーティションのサイズは少なくとも16MB必要です。これより少ない場合は、パラレル問合せで効果的なスキャン率がでません。

ハッシュ・パーティション化の主なパフォーマンスの利点の1つは、パーティション・ワイズ結合です。パーティション・ワイズ結合では、結合がパラレルで実行されるときにパラレル実行サーバー間で交換されるデータ量が最小限に抑えられ、問合せのレスポンス時間が短縮されます。レスポンス時間は大幅に短縮され、CPUとメモリー・リソースの使用率が改善されます。クラスタ化されたデータ・ウェアハウスで、大規模な結合操作で優れたスケーラビリティを実現するために重要なインターコネクト(IPC)でのデータ・トラフィックを制限して、レスポンス時間が大幅に短縮されます。パーティション・ワイズ結合は、結合する表のパーティション・スキームによってフルまたはパーシャルになります。

フル・パーティション・ワイズ結合は、2つの大きい表の結合を複数の小さい結合に分割します。小さい各結合は、結合される表ごとに、パーティションのペアの結合を実行します。フル・パーティション・ワイズ結合方法を選択するオプティマイザには、両方の表を結合キーでパーティション化する必要があります。つまり、同じパーティション化方法を使用した同じ列でパーティション化する必要があります。フル・パーティション・ワイズ結合のパラレル実行はシリアル実行と似ていますが、一度に1つのパーティション・ペアを結合するかわりに複数のパーティション・ペアを複数のパラレル問合せサーバーで結合する点が異なります。パラレルで結合するパーティションの数は、並列度(DOP)によって決定されます。

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

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

図4-4に、SalesおよびCustomersの2つの表間のフル・パーティション・ワイズ結合のパラレル実行を示します。両方の表の並列度およびパーティション数は同じです。日付フィールドでレンジ・パーティション化され、cust_idフィールドでハッシュを使用してサブパーティション化されます。図に示すように、各パーティション・ペアがデータベースから読み取られ、直接結合されます。データの再分散が必要ないため、特にノード間でIPC通信を最小化します。次の図4-5に、この結合を確認する実行計画を示します。

パラレルでパーティション・ワイズ結合を実行する場合に最適なパフォーマンスを取得するには、各表のパーティションの数が結合に使用する並列度よりも大きい必要があります。パラレル・サーバーよりも多くのパーティションがある場合、各パラレル・サーバーに結合するパーティションの1つのペアが提供され、パラレル・サーバーが結合を完了すると、結合する別のペアのパーティションがリクエストされます。すべてのペアが処理されるまで、このプロセスが繰り返されます。この方法により、動的にロード・バランスできます(たとえば、並列度32の128個のパーティションなど)。

結合している表の1つのみをパーティション化するとどうなるのでしょうか。この場合、オプティマイザはパーシャル・パーティション・ワイズ結合を選択できます。フル・パーティション・ワイズ結合とは異なり、1つの表のみが結合キーでパーティション化されている場合にパーシャル・パーティション・ワイズ結合を適用できます。したがって、パーシャル・パーティション・ワイズ結合は、フル・パーティション・ワイズ結合よりも一般的です。パーシャル・パーティション・ワイズ結合を実行するために、Oracleによって、パーティション表のパーティション化戦略に基づいて、もう一方の表が動的に再パーティション化されます。もう一方の表が再パーティション化された後は、フル・パーティション・ワイズ結合と同様に実行されます。再分散操作には、パラレル実行サーバー間での行の交換が伴います。データをノード境界で再パーティション化する必要があるため、この操作は、Oracle RAC環境のインターコネクト・トラフィックにつながります。

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

図4-5の説明は図の下のリンクをクリックしてください。
「図4-5 パーシャル・パーティション・ワイズ結合」の説明

図4-5に、パーシャル・パーティション・ワイズ結合を示します。図4-4と同じ例を使用しますが、顧客表がパーティション化されない点が異なります。結合操作を実行する前に、顧客表の行が結合キーで動的に再分散されます。

3NFスキーマ: パラレル問合せの実行

3NFスキーマではパラレル化を複数の方法で活用できますが、ここでは3NFにとって特別な意味のある、パラレル化の1つの側面に注目します。それは大規模問合せでのSQLパラレル実行です。Oracle DatabaseでのSQLパラレル実行は、コーディネータ(通常、問合せコーディネータまたはQCと呼ばれる)およびパラレル・サーバーの原則に基づきます。QCはパラレルSQL文を起動するセッションで、パラレル・サーバーはパラレルで動作する個別のセッションです。QCは処理をパラレル・サーバーに分散するため、パラレルで実行できない最低限の主にロジスティックな処理を実行する必要があります。たとえば、SUM()演算を含むパラレル問合せでは、各パラレル・サーバーで計算された小計それぞれを合計する必要があります。

図4-5のPX COORDINATORで示すとおり、QCはパラレル実行で容易に識別できます。パラレルSQL操作のQCとして動作するプロセスは、実際のユーザー・セッション・プロセスそのものです。パラレル・サーバーは、グローバルに使用可能なパラレル・サーバーのプロセスのプールから取得され、特定の操作に割り当てられます。パラレル・サーバーは、QCの下位のパラレル計画にあるすべての処理を実行します。

Oracle Databaseは、デフォルトで設定不要なパラレル実行をサポートするよう構成されており、2つの初期化パラメータ、parallel_max_serversおよびparallel_min_serversで制御されます。パラレル実行は非常に強力でスケーラブルなフレームワークを提供し、SQL操作をスピードアップしますが、常識的なルールの適用を忘れてはいけません。つまり、パラレル実行によりさらなるパフォーマンスの向上が見込めますが、より多くのリソースが必要になり、同じシステムの他のユーザーや操作に影響する可能性があります。小規模の表や索引(数千レコードまでのもの、数十データ・ブロックまでのもの)では、パラレル実行を有効にしないでください。小規模表のみに該当する操作には、パラレルで実行するメリットがあまりありませんが、大規模表にアクセスする操作で使用するパラレル・サーバーが使用されます。特定の並列度(DOP)でいったん操作が始まると、実行中にDOPを下げる手段がないことにも注意してください。

あるオブジェクトに対して、適切なDOPを決定する一般的な経験則は次のとおりです。

  • 200 MB未満のオブジェクトではパラレル化を使用しないでください。

  • 200 MBから5GBまでのオブジェクトではDOPを4にする必要があります。

  • 5GB超のオブジェクトでは、DOPを32にしてください。

いうまでもなく、サイズ・レンジやDOPにおいてシステムの最適な設定は異なる上、対象のワークロード、ビジネス要件およびハードウェア構成に高く依存します。Oracle RACにおけるインスタンス間パラレル実行の使用の可否では、Oracle RAC環境でのパラレル実行について説明しています。

Oracle RACにおけるインスタンス間パラレル実行の使用の可否

Oracle Databaseでは、デフォルトでノード間パラレル実行が可能です(複数ノードを含む単一の文のパラレル実行)。前述のとおり、ノード間パラレル実行によってインターコネクト・トラフィックが増大する可能性があるため、Oracle RAC環境でのインターコネクトのサイズが適切である必要があります。サーバーからストレージ・サブシステムへのI/O帯域幅に対し、比較的弱いインターコネクトを使用している場合、パラレル実行を単一ノードまたは限られたノード数に制限することをお薦めします。ノード間パラレル実行は、インターコネクトのサイズが小さいと対応できません。Oracle Database 11g以降では、Oracle RACサービスを使用して、クラスタ上でパラレル実行を制御することをお薦めします。

VECTOR GROUP BY集計を使用したスター・クエリーの最適化

VECTOR GROUP BY集計は、データを集計し、1つ以上の比較的小さな表をより大きな表に結合する問合せを最適化します。この変換は、SQLオプティマイザによって、コスト見積もりに基づいて選択されることがあります。データ・ウェアハウジングのコンテキストでは、VECTOR GROUP BYは、インメモリー列表からデータを選択するスター・クエリーの場合によく選択されます。

VECTOR GROUP BY集計は、小さな表と大きな表の間の結合条件を、より大きな表の上のフィルタに変換するという点で、ブルーム・フィルタと類似しています。VECTOR GROUP BY集計は、ファクト表のスキャン後に別の手順としてデータを集計するのでなく、スキャン時に行うことによって、問合せパフォーマンスをさらに向上させます。

関連項目: