14 ゾーン・マップの使用

ゾーン・マップは、表に対して作成できる、独立したアクセス構造です。表スキャンおよび索引スキャンにゾーン・マップを使用すると、表列上の述語に基づいて、表のディスク・ブロックや、パーティション表の完全なパーティションをプルーニングできる可能性があります。ゾーン・マップは、属性クラスタリングの有無にかかわらず使用できます。

この章の内容は次のとおりです。

14.1 ゾーン・マップについて

ゾーンマップは表に対して作成される独立したアクセス構造で、表のゾーンに関する情報が格納されます。ゾーン・マップを使用すると、表列上の述語に適合しないデータ・ブロックをデータベースがプルーニングできます。ゾーンとは、ディスク上で連続している一群のデータ・ブロックです。

従来のゾーン・マップは、ディスク・ユニット、ブロックまたはエクステントごとに表内の列の最小値と最大値を格納します。問合せがクラスタリング列を修飾する場合、I/Oプルーニングが発生します。Oracle Databaseのゾーン・マップは、一定範囲のブロック(ゾーンと呼ばれます)について、列の最小値と最大値を格納します。ファクト表がディメンション表との外部結合を介してディメンション属性により属性クラスタリングされていれば、クラスタリングされたファクト表の述語に基づくI/Oプルーニングの実行に加え、ゾーン・マップはディメンション表の述語上でもプルーニングします。

1つの表につき最大1つのゾーン・マップを定義できます。パーティション表の場合、すべてのパーティション(およびサブパーティション)について1つのゾーン・マップが存在します。パーティション表のゾーン・マップは、ゾーンごと、パーティションごと、サブパーティションごとの最小値と最大値を追跡します。表にディメンション表との外部結合がある場合、ゾーン・マップ定義にディメンション列の最小値と最大値を含めることができます。

この項では、次の項目について説明します。

14.1.1 ゾーン・マップと索引の違い

ゾーン・マップは、粗い索引構造のようなものです。ただし、索引とは次のような根本的な違いがあります。

  • ゾーン・マップには、行ごとではなくゾーンごとの情報が格納されます。このため、索引よりはるかにコンパクトです。

  • 索引はDML処理との同期を維持しますが、ゾーン・マップは、そのようにアクティブには管理されません。このため、たとえゾーン・マップにREFRESH ON COMMITオプションが付けられていても、コミットまたはロールバックが発生するまで、トランザクション範囲内では失効していることがあります。

  • ゾーン・マップには、あるゾーンに関する失効した情報と、残りのゾーンに関する新しい情報が混在することがありますが、その場合もOracle Databaseでは、ファクト表のスキャン時に、そのゾーン・マップを使用してI/Oプルーニングを実行します。

14.1.2 ゾーン・マップと属性クラスタリング

属性クラスタリングは、ゾーン・マップにとって必須の前提条件ではありません。ゾーン・マップは、属性クラスタリングの有無にかかわらず使用できます。このため、ゾーン・マップがなくても属性クラスタリングを指定でき、クラスタリングがなくても表上でゾーン・マップを作成できます。

データ・ウェアハウジング環境では、ETL処理のデータを合理的にクラスタリングしているのが普通です(たとえば、時間列や地理的リージョンによるクラスタリング)。クラスタリングにより、列の最小値と最大値が、属性クラスタリングされた表内の連続的なデータ・ブロックと相関する傾向が高まるため、ゾーン・マップを使用するプルーニングの効率が向上します。ゾーン・マップを使用すると、属性クラスタリングにより実行されるデータの順序付けを利用できるため、プルーニングが効率化します。表スキャンと索引スキャンの際(たとえば、rowidによるフェッチ)、ゾーン・マップを使用すると、表列の述語に適合しないデータ・ブロックもプルーニングできます。

関連項目:

属性クラスタリングの詳細は、属性クラスタリングについてを参照してください。

14.1.3 ゾーン・マップのタイプ

ゾーン・マップには、次の2つのタイプがあります。

  • 基本的なゾーン・マップは単一の表の上で定義され、この表の一部の列の最小値と最大値を保持します。

  • 結合ゾーン・マップは、1つ以上の別の表への外部結合を持っており、その別の表内の一部の列の最小値と最大値を保持している表の上で定義されます。これらの結合条件はマスターと詳細の関係でも、ファクト表とディメンション表の間のスター・スキーマでも一般的です。

    スター・クエリーの場合、複数のディメンション表が、ファクト表とのPK-FK関係を介して結合されます。ここで、結合ゾーン・マップは、ファクト表のゾーンに対応するディメンション表の列の最小値と最大値を維持します。

14.1.4 ゾーン・マップの利点

  • 表または表パーティションの順次スキャンまたは索引スキャン時のI/Oを削減

  • ゾーン・マップ列がパーティション化キーと相関している場合に、パーティション表やコンポジット・パーティション表の非キー列に基づくパーティション・プルーニングが可能

  • インターリーブ順序による属性クラスタリングで、クラスタリング列のサブセットにおけるI/O削減を可能にします。

  • 索引の使用に関連する記憶域コストが不要

14.1.5 ゾーン・マップが有効なシナリオ

ゾーン・マップは、次のシナリオで有効です。

  • 表スキャンが、使用頻度の高い述語を使用して実行される

    ゾーン・マップを使用すると、列述語によって除外されたゾーンをOracle Databaseがスキャンせずにすみます。

  • 結合が、ディメンション階層列上で使用頻度の高い述語を使用して、ファクト表とディメンション表の間で定義される

    ファクト表の行を、属性値上の述語によって除外されるゾーンをプルーニングしつつ、ディメンション属性値により順序付けることができます。

  • パーティション表内の列に、パーティション・キーと相関する値が含まれる

    これにより、非キー列に基づくパーティション・プルーニングが容易になります。たとえば、日付でパーティション化されている表には、パーティション・キーとよく相関する他の日付列や、時間の経過に応じて変化または循環する連続値を含む列がしばしばあります。

  • データ・クラスタリングがゾーン・マップ列の値に対して実行される

    属性クラスタリングは、特にこの目的のために設計されています。あるいは、データに内在する順序を利用するのが適切です(たとえば、順次的にロードされる、時間に基づく列値や、ロード時にソートされるデータ)。

  • 頻度が高くカーディナリティが低い索引範囲スキャンが、表の上で実行される

    属性クラスタリングを単独で使用して、圧縮係数を改善できます。ゾーン・マップを使用すると、除外されたゾーンからの参照をプルーニングすることによって、索引スキャンの効率を改善できます。あるいは、ゾーン・マップを索引のかわりに使用できます。

14.1.6 ゾーン・マップのメンテナンスについて

ゾーン・マップは表に基づいているため、基礎になる表に対する変更はなんであれ、ゾーン・マップの状態に影響します。表の上で実行される操作により異なりますが、ゾーン・マップの一部またはすべてのゾーンが影響を受けます。基礎になる表の変更により影響がおよぶゾーン・マップにはメンテナンスが必要です。

ゾーン・マップのメンテナンスは、次のうち1つ以上の作業で構成されます。

  • 影響を受けるゾーン・マップの有効性チェック

  • 影響を受けるゾーンの失効追跡

  • 影響を受ける失効済ゾーン・マップのリフレッシュ(ゾーン・マップに対して設定されているリフレッシュ・モードにより異なる)

ゾーン・マップが基づいている実表の構造が変更された場合(たとえば、最小値と最大の値がゾーン・マップによって維持されている表列が削除されたなどの場合)、ゾーン・マップは無効になります。無効なゾーン・マップは問合せで使用されず、そのゾーン・マップはOracle Databaseではメンテナンスされません。ただし、ゾーン・マップと関連していない実表の構造が変更された場合(たとえば、表に新規の列が追加された場合など)、ゾーン・マップは有効なままですが、コンパイルが必要です。Oracle Databaseは、それ以降の操作(問合せによるゾーン・マップの使用など)の際に、ゾーン・マップを自動的にコンパイルします。または、ALTER MATERIALIZED ZONEMAPコマンドのCOMPILE句を使用してゾーン・マップをコンパイルすることもできます。

基礎になる表のデータが変更された場合、その変化の影響を受けるゾーンは「失効」とマークされます。失効したゾーン・マップでは、データだけは最新ではありませんが、定義はまだ有効です。Oracle Databaseは、様々なタイプの操作による、基礎になる表上でのゾーン・マップの失効を自動的に追跡します。基礎になる表の上で実行される操作のタイプに応じて、Oracle Databaseは、ゾーン・マップ全体を失効とマークするか、ゾーン・マップ内の一部のゾーンのみを失効とマークします。

この項では、次の項目について説明します。

14.1.6.1 ゾーン・マップのメンテナンスを必要とする操作

ゾーン・マップのメンテナンスが必要になるのは、基礎になる表の1つ以上に対して次の操作が行われる場合です。

  • DML(挿入、削除、更新、従来型ロード)。

  • 直接パス挿入およびロード。

  • パーティションのメンテナンス操作(MOVESPLITMERGEDROPTRUNCATEおよびEXCHANGE)、表データの移動、および表のオンライン再定義。

14.1.6.2 ゾーン・マップが自動的にリフレッシュされるシナリオ

前述の操作の影響を受けたゾーン・マップをOracle Databaseが自動的にリフレッシュするかどうかは、ゾーン・マップ・リフレッシュ・モードにより決定されます。

Oracle Databaseでは、次のものに影響を受けるゾーン・マップについて自動リフレッシュが実行されます。

  • リフレッシュ・モードがREFRESH ON COMMITの場合、DML操作。REFRESH ON COMMITモードのゾーン・マップは、トランザクション的には最新のままです。リフレッシュは、トランザクションがコミットされたときに実行されます。

  • リフレッシュ・モードがREFRESH ON LOADの場合、直接パス挿入またはロード。

    REFRESH ON LOADで構成されているゾーン・マップは、基礎になる表の上でのDMLまたはPMOP操作により失効することがあります。

  • リフレッシュ・モードがREFRESH ON DATA MOVEMENTである場合、PMOP(MOVESPLITMERGEDROP)または表の移動。

    REFRESH ON DATA MOVEMENTで構成されているゾーン・マップは、DML、直接パス挿入またはロード、PMOP(TRUNCATEEXCHANGE)または基礎になる表のオンライン再定義の後、失効することがあります。

  • リフレッシュ・モードがREFRESH ON DATA MOVEMENTである場合の、直接パス挿入またはロード、PMOP(MOVESPLITMERGEDROP)または表の移動。

    REFRESH ON LOAD DATA MOVEMENTで構成されているゾーン・マップは、DML、PMOP(TRUNCATEEXCHANGE)または基礎になる表のオンライン再定義の後、失効することがあります。

リフレッシュ・モードがREFRESH ON DEMANDの場合、Oracle Databaseは基礎になる表でのなんらかの操作に影響を受けるゾーン・マップを自動リフレッシュしません。REFRESH ON DEMANDが設定されているゾーン・マップは、手動でリフレッシュする必要があります。

14.2 ゾーン・マップの操作

この項では、ゾーン・マップを含む一般的なタスクについて、次のように分けて説明します。

14.2.1 ゾーン・マップに必要な権限

  • 独自のスキーマのゾーン・マップを作成、変更または削除するには、CREATE MATERIALIZED ZONEMAP権限を持っている必要があります。

  • 他のスキーマのゾーン・マップを作成するには、CREATE ANY MATERIALIZED ZONEMAP権限を持っている必要があります。

  • 別のスキーマの表の上に、独自のスキーマのゾーン・マップを作成するには、SELECT ANY TABLEまたはREAD ANY TABLE権限を持っている必要があります。

  • 他のスキーマの表を使用して他のスキーマのゾーン・マップを作成するには、SELECT ANY TABLEおよびCREATE ANY MATERIALIZED ZONEMAP権限を持っている必要があります。SELECT ANY TABLE権限のかわりにREAD ANY TABLE権限を持つこともできます。

  • 他のスキーマのゾーン・マップを変更するには、ALTER ANY MATERIALIZED ZONEMAP権限を持っている必要があります。

  • 他のスキーマのゾーン・マップを削除するには、DROP ANY MATERIALIZED ZONEMAP権限を持っている必要があります。

14.2.2 ゾーン・マップの作成

ゾーン・マップは属性クラスタリングとともに表の上に作成できますが、ゾーン・マップは属性クラスタリングから独立しています。ゾーン・マップは、属性クラスタリングにかかわりなく、独立して作成できます。

ゾーン・マップが使用する記憶域の構造は、それが定義される表のデフォルト表領域に作成されます。

関連項目:

  • ゾーン・マップ作成の構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

  • ゾーン・マップの制限事項の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

この項では、次の項目について説明します。

14.2.2.1 属性クラスタリングによるゾーン・マップの作成

WITH MATERIALIZED ZONEMAP副次句を使用して、ゾーン・マップを作成できます。表に属性クラスタリングを定義する場合、または、後でクラスタリング定義を変更する場合、この副次句を使用できます。

属性クラスタリングを使用してゾーン・マップを作成するには、次のトピックで説明されているステップを使用します。

14.2.2.1.1 線形属性クラスタリングによる基本的なゾーン・マップの作成

salesの問合せで、顧客ID、または顧客IDと製品IDの組合せがよく指定される事態を想定します。問合せでゾーン・マップを使用したプルーニングを活用できるように、属性クラスタリングされた表を作成することができます。次のような表を作成するとします。

CREATE TABLE sales (
   prod_id NUMBER NOT NULL,
   cust_id NUMBER NOT NULL,
   time_id        DATE NOT NULL,
   channel_id     NUMBER NOT NULL,
   promo_id       NUMBER NOT NULL,
   quantity_sold  NUMBER(10,2),
   amount_sold NUMBER(10,2)
)
CLUSTERING
BY LINEAR ORDER (cust_id, prod_id)
YES ON LOAD YES ON DATA MOVEMENT
WITH MATERIALIZED ZONEMAP;

列(cust_idprod_id)上にゾーン・マップZMAP$_SALESが作成されます。ここで、ZMAP$_SALESは、Oracle Databaseによって自動的に生成されるゾーン・マップの名前です。ただし、インターリーブ属性クラスタリングによる結合ゾーン・マップの作成で説明するとおり、WITH MATERIALIZED ZONEMAPに続けてカッコに入れることでゾーン・マップの名前を指定できます。

cust_idprod_idの両方、または接頭辞cust_idを修飾する問合せは、自然プルーニングを受けます。次の例は、表スキャン時のデータベースのプルーニングがどのように可能になるかを示しています。

アプリケーションは、次の問合せを発行します。

SELECT * FROM sales WHERE cust_id = 100;

表はBY LINEAR ORDERでクラスタリングされているため、データベースはcust_idの値に100が含まれるゾーンのみ読み取る必要があります。

アプリケーションは、次の問合せを発行します。

SELECT * FROM sales WHERE cust_id = 100 AND prod_id = 2300;

表はBY LINEAR ORDERでクラスタリングされているため、データベースはcust_idの値に100、prod_idの値に2300が含まれるゾーンのみ読み取る必要があります。

14.2.2.1.2 インターリーブ属性クラスタリングによる結合ゾーン・マップの作成

salesファクト表と、その2つのディメンション表、customersおよびproductsを含むデータ・ウェアハウスを想定します。大部分の問合せは、customers表階層(country_id, cust_state_province, cust_city)およびproducts階層(prod_category, prod_subcategory)上の述語を持っています。次の部分文に示すように、sales表のインターリーブ順序を使用できます。

CREATE TABLE sales (
   prod_id NUMBER NOT NULL,
   cust_id NUMBER NOT NULL,
   amount_sold NUMBER(10,2))
CLUSTERING
sales JOIN products ON (sales.prod_id = products.prod_id)
JOIN customers ON (sales.cust_id = customers.cust_id)
BY INTERLEAVED ORDER
(
(products.prod_category, products.prod_subcategory),
(customers.country_id, customers.cust_state_province, customers.cust_city)
)
YES ON LOAD YES ON DATA MOVEMENT
WITH MATERIALIZED ZONEMAP (sales_zmap);

属性クラスタリングされた表に、sales_zmapと呼ばれるゾーン・マップが作成されます。このクラスタリング句では、ディメンション表の結合列に主キーまたは一意キーの制約がある必要があります。1つのディメンションからのインターリーブ順序の列の場合、たとえば(prod_category, prod_subcategory)のように「(」と「)」で囲んだ別のグループがクラスタリング句になければならないことに注意してください。さらに、列はディメンション内の階層に従う必要があり(たとえばprod_category, prod_subcategoryの自然階層)、グループ内の列の順序は階層内のものに従う必要があります。これにより、ディメンション表に存在する階層に応じて、データが効果的にクラスタリングされます。

14.2.2.1.3 属性クラスタリング後のゾーン・マップ作成

データベースにsalesと呼ばれている表が存在すると想定します。次のコマンドを使用して、sales表に属性クラスタリングを定義することができます。

ALTER TABLE sales ADD CLUSTERING BY INTERLEAVED ORDER (cust_id, prod_id)
      YES ON LOAD YES ON DATA MOVEMENT;

このコマンドは、表定義に属性クラスタリングを追加しますが、sales表内の既存のデータはクラスタリングしません。sales表上でデータ移動操作を実行すると、YES ON DATA MOVEMENTオプションがあるため、そのデータはクラスタリングされます。

次のコマンドは、sales表内のデータをクラスタリングします。

ALTER TABLES sales MOVE;

sales表内のデータがクラスタリングされた後、次のコマンドを使用してクラスタリングを変更することによって、sales表上にゾーン・マップを定義できます。

ALTER TABLE sales MODIFY CLUSTERING WITH MATERIALIZED ZONEMAP (sales_zmap);

その後、必要なら、次のコマンドを使用してクラスタリングを変更することによってゾーン・マップを削除できます。

ALTER TABLE sales MODIFY CLUSTERING WITHOUT MATERIALIZED ZONEMAP;
14.2.2.2 属性クラスタリングから独立したゾーン・マップの作成

表上にゾーン・マップを作成するには、CREATE MATERIALIZED ZONEMAPコマンドを使用します。このゾーン・マップは属性クラスタリングから独立しています。これは、クラスタリングされた表にもクラスタリングされていない表にも作成できるということです。また、ゾーン・マップに使用される列の組合せは、属性クラスタリングに使用される列の組合せと同じでも異なっていてもかまいません。

ゾーン・マップを作成する場合、ゾーン・マップが基づく表の列を指定する必要があります。

属性クラスタリングから独立したゾーン・マップを作成するには、次のトピックで説明されているステップを使用します。

14.2.2.2.1 属性クラスタリングから独立した基本ゾーン・マップの作成

sales表上の問合せで、顧客ID、製品ID、またはその2つの列の組合せがよく指定されると想定します。例14-1に示すように、プルーニングが問合せを効率化できるように、sales表の顧客ID列と製品ID列の上にゾーン・マップを作成できます。

例14-1 属性クラスタリングから独立した基本ゾーン・マップの作成

次の文を使用して、sales表の上にゾーン・マップsales_zmapを作成できます。

CREATE MATERIALIZED ZONEMAP sales_zmap ON sales (cust_id, prod_id);

この文は、次のCREATE...AS文と同じです。

CREATE MATERIALIZED ZONEMAP sales_zmap
REFRESH ON LOAD DATA MOVEMENT
AS
SELECT SYS_OP_ZONE_ID(rowid),MIN(cust_id),MAX(cust_id),MIN(prod_id),MAX(prod_id)
FROM sales
GROUP BY SYS_OP_ZONE_ID(rowid);

この文では、ゾーン・マップで使用するSYS_OP_ZONE_ID(rowid)ファンクションが使用されています。SYS_OP_ZONE_IDファンクションは、ファクト表行のrowidが指定されると、隣接するディスク・ブロック(ゾーン)の個別の範囲を特定します。このファンクションは、ゾーン・マップのパーティション・プルーニングと高速リフレッシュを実行して、パーティション・レベルで最小値と最大値の範囲を維持する助けになります。ゾーン・マップで使用する場合、隣接するデータ・ブロック群から単一のゾーンにすべての行をマップすると便利です。

14.2.2.2.2 属性クラスタリングから独立した結合ゾーン・マップの作成

salesファクトと複数のディメンションを含むデータ・ウェアハウスを想定します。大部分の問合せは、customers表階層(cust_state_province, cust_city)上の述語を持っています。例14-2に示すように、sales表ではインターリーブ順序を使用できます。

例14-2 属性クラスタリングから独立した結合ゾーン・マップの作成

結合ゾーン・マップには、ゾーン・マップが作成されている表から、他の1つ以上の表への外部結合が含まれます。次の文に示すように、結合ゾーン・マップはスター・スキーマ設定で最も一般的に使用され、ファクト表の列でなく、ディメンション表の列の最小値と最大値を追跡します。

CREATE MATERIALIZED ZONEMAP sales_zmap
REFRESH ON LOAD DATA MOVEMENT
AS
SELECT SYS_OP_ZONE_ID(s.rowid), MIN(cust_state_province), 
       MAX(cust_state_province), MIN(cust_city), MAX(cust_city)
FROM sales s, customers c
WHERE s.cust_id = c.cust_id(+)
GROUP BY SYS_OP_ZONE_ID(s.rowid);

14.2.3 ゾーン・マップの変更

ALTER MATERIALIZED ZONEMAP文を使用してゾーン・マップを変更できます。

例14-3 ゾーン・マップの使用不能化

次の文は、ゾーン・マップを使用不能にします。これは、問合せがこのゾーン・マップをもう使用せず、Oracle Databaseによるゾーン・マップのメンテナンスも行われないことを意味します。

ALTER MATERIALIZED ZONEMAP sales_zmap UNUSABLE;

例14-4 ゾーン・マップの完全リフレッシュの実行

次の文は、ゾーン・マップの完全リフレッシュを実行します。

ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD COMPLETE;

ゾーン・マップがそれ以前に使用不能とマークされている場合、再構築の過程で使用可能にされます。

例14-5 ゾーン・マップのリフレッシュ

次の文は、可能な場合、高速リフレッシュを実行します。それ以外の場合は完全リフレッシュを実行します。

ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD;

例14-6 ゾーン・マップのプルーニングの無効化

次の文はプルーニングを無効にします。これはパフォーマンス測定の際に必要になることがあります。

ALTER MATERIALIZED ZONEMAP sales_zmap DISABLE PRUNING;

例14-7 ゾーン・マップのプルーニングの有効化

次の文は、以前に無効化されている可能性があるゾーン・マップのプルーニングを有効化します。

ALTER MATERIALIZED ZONEMAP sales_zmap ENABLE PRUNING;

例14-8 ゾーン・マップのリフレッシュの無効化

次の文は、ロード時のリフレッシュとデータ移動をオフにし、それにより、ゾーン・マップがリフレッシュされる方法とタイミングを制御できるようにします。

ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON DEMAND;

例14-9 コミット時のゾーン・マップ・リフレッシュの有効化

次の文は、各トランザクションのコミット時におけるゾーン・マップのリフレッシュをオンにします。

ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON COMMIT;

関連項目:

14.2.4 ゾーン・マップの削除

次のように、DROP MATERIALIZED ZONEMAP文を発行することによってゾーン・マップを削除できます。

DROP MATERIALIZED ZONEMAP sales_zmap;

関連項目:

ゾーン・マップ削除の構文については、『Oracle Database SQL言語リファレンス』を参照してください。

14.2.5 ゾーン・マップのコンパイル

ゾーン・マップが基づいている実表に関するDDL操作はすべて、ゾーン・マップのコンパイル状態に影響を及ぼします。このため、ゾーン・マップがまだ有効かどうか確認するには、ゾーン・マップを定義する問合せをコンパイルする必要があります。この動作はマテリアライズド・ビューと類似しています。それも実表で実行されるDDLの影響を受けるためです。Oracle Databaseは、DDL操作後、ゾーン・マップを初めて使用しようとするときにコンパイルします。ただし、次のようなDDL変更文を使用して、ゾーン・マップを明示的にコンパイルすることができます。

ALTER MATERIALIZED ZONEMAP sales_zmap COMPILE;

ゾーン・マップのコンパイル結果は、DDLによって実行された個別処理に応じて、有効か無効のいずれかです。たとえば、ファクト表に列を追加するためにDDLが実行された場合、ゾーン・マップはコンパイル後に有効になります。一方、定義問合せで参照された列を削除するためにDDLが実行された場合、ゾーン・マップはコンパイル後に無効になります。

注意すべきポイントは次のとおりです。

  • クラスタリング句に出現する列が削除されると、クラスタリングは削除されます。また、クラスタリングの一部として作成されたゾーン・マップがあれば、そのゾーン・マップも削除されます。

  • スター・スキーマからのディメンション表が削除され、それがファクト表上のクラスタリングに含まれていた場合、そのファクト表のクラスタリングは削除されます。また、クラスタリングの一部として作成されたゾーン・マップがあれば、そのゾーン・マップは削除されます。

  • ユーザーがクラスタリング句に含まれるディメンション表上の必須の主キーまたは一意キーを削除した場合、クラスタリングは無効にされます(一部のタイプのPMOPがそれ以降にロードまたはデータ移動操作を実行しても、データのクラスタリングが行われません)。

14.2.6 ゾーン・マップ使用の制御

SQLワークロード全体または特定のSQL文に対してゾーン・マップの使用を制御することができます。

この項では、次の項目について説明します。

14.2.6.1 SQLワークロード全体に対するゾーン・マップ使用の制御

オブジェクト・レベルでゾーン・マップの使用を制御できます。オブジェクト・レベルの変更は、SQLワークロードのすべての文に適用されます。ゾーン・マップを作成すると、DISABLE PRUNINGを指定してデフォルトをオーバーライドしないかぎり、プルーニングに利用できます。たとえば、次の文は、プルーニング無効でゾーン・マップを作成します。

CREATE MATERIALIZED ZONEMAP sales_zmap 
    DISABLE PRUNING ON sales(cust_id, prod_id);

このゾーン・マップは、Oracle Databaseによって作成、メンテナンスされますが、ワークロード内のいかなるSQLでも使用されません。次のALTER MATERIALIZED ZONEMAP文を使用すると、プルーニングで利用できるようにできます。

ALTER MATERIALIZED ZONEMAP sales_zmap ENABLE PRUNING;

同様に、次の文を使用すると、ゾーン・マップをプルーニングに利用できないようにできます。

ALTER MATERIALIZED ZONEMAP sales_zmap DISABLE PRUNING;
14.2.6.2 特定のSQL文に対するゾーン・マップ使用の制御

ヒントを使用して、個別のSQL文レベルでゾーン・マップの使用を制御できます。ゾーン・マップに対してプルーニングが無効にされている場合、ヒントを使用してゾーン・マップの使用を制御できないことに注意してください。プルーニングは有効なままにしておき、個別のSQL文で否定的なヒントを指定することで、ヒントを介してより細かく制御できます。

プルーニングによるゾーン・マップの使用を無効にするには、NO_ZONEMAPヒントを使用します。次の例は、データをプルーニングしますが、ゾーン・マップの使用を無効にします。

例14-10 スキャン・プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化

SELECT /*+ NO_ZONEMAP (S SCAN) */* FROM sales S
WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';

例14-11 結合プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化

SELECT /*+ NO_ZONEMAP (S JOIN) */* FROM sales s
WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';

例14-12 パーティション・プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化

SELECT /*+ NO_ZONEMAP (S PARTITION) */* FROM sales S
WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';

14.2.7 ゾーン・マップのメンテナンス

ゾーン・マップの作成時、または後でゾーン・マップ定義を変更するときに、ゾーン・マップをメンテナンスする方法を指定できます。ゾーン・マップ・メンテナンスに関する考慮事項を参照してください。

ゾーン・マップのメンテナンス方法を指定するには、CREATE MATERIALIZED ZONEMAPまたはALTER MATERIALIZED ZONEMAP文でREFRESH句を使用します。CREATE MATERIALIZED ZONEMAP文でREFRESH句を省略する場合、使用されるデフォルトはREFRESH ON LOAD DATA MOVEMENTとなり、直接パス・ロード時と一部のデータ移動操作時の、Oracle Databaseによるゾーン・マップのメンテナンスが有効になります。

次の文は、メンテナンスをユーザーが手動で管理するゾーン・マップを作成します。

CREATE MATERIALIZED ZONEMAP sales_zmap
REFRESH ON DEMAND 
ON sales (cust_id, prod_id);

次の文は、メンテナンスが各トランザクションのコミット終了時にOracle Databaseによって管理されるゾーン・マップを作成します。

CREATE MATERIALIZED ZONEMAP sales_zmap 
REFRESH ON COMMIT 
ON sales (cust_id, prod_id);

コミット時にリフレッシュされるため、前述のゾーン・マップは決して失効しません。

既存のゾーン・マップのメンテナンスを変更するには、ALTER MATERIALIZED ZONEMAP文を使用します。

例14-13 データ移動時におけるゾーン・マップ・メンテナンスの有効化

次の文は、Oracle Databaseによる、データ移動操作時(たとえばMOVESPLITMERGEおよびDROP)のゾーン・マップ・メンテナンスを有効にします。

ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON DATA MOVEMENT;

例14-14 直接パス・ロード時におけるゾーン・マップ・メンテナンスの有効化

次の文は、Oracle Databaseによる直接パス・ロード操作時(INSERT /*+ APPEND */文など)のゾーン・マップ・メンテナンスを有効にします。

ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON LOAD;

例14-15 データの移動およびロード時におけるゾーン・マップ・メンテナンスの有効化

次の文は、Oracle Databaseによる、データ移動およびロード操作時のゾーン・マップ・メンテナンスを有効にします。

ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON LOAD DATA MOVEMENT;

REFRESH ON LOAD DATA MOVEMENTがデフォルトのオプションである点に注意してください。

14.2.7.1 ゾーン・マップ・メンテナンスに関する考慮事項

ゾーン・マップのメンテナンスと失効の追跡に関する、注意が必要な問題のいくつかを次に示します。

  • ファクト表に対するDML/パラレルDML操作

    ゾーン・マップが作成されると、従来のDML操作による行の変更を追跡するための内部トリガーが作成されます。たとえば、sales表に新しい行が挿入されると、そのトリガーがrowidからzone_idを計算し、ゾーン・マップ内の対応する集計行を失効としてマークします。このため、ゾーン・マップの失効はゾーンごとに追跡されます。これは、ファクト表に対してDMLが実行された後でさえ、そのゾーン・マップが、最新のゾーンのMIN/MAX集計を使用するプルーニングに使用されることがまだあることを意味します。

    ファクト表更新時点で、更新される列がゾーン・マップによって参照されていない場合、ゾーン・マップの失効は影響を受けません。それ以外の場合、更新された行に対応するゾーンは、内部トリガーによって失効とマークされます。

  • ファクト表への直接ロード(INSERT /*+ APPEND */)操作

    直接ロードが最高水位標より上にデータを挿入する場合も、新しく追加される行は、そのゾーン・マップに対してすでに計算済のゾーンに属することができます。このため、Oracle Databaseは、MIN/MAX集計が新しく追加されるデータに影響を受ける可能性のある既存のゾーンを識別し、そのようなゾーンを失効とマークします。また、まだ最新状態であるゾーンのMIN/MAX集計を利用することによって、ゾーン・マップへの直接ロードにもかかわらず、プルーニングでのゾーン・マップ利用をOracle Databaseで継続できます。ゾーン・マップにREFRESH ON LOADオプションがある場合、Oracle Databaseはロード終了時にゾーン・マップ・リフレッシュを実行します。

  • ファクト表でのデータ移動(たとえば、パーティション・メンテナンス操作)

    データ移動操作には、パーティション・メンテナンス操作や、パーティション/表のオンライン再定義が含まれます。ただし、データ移動(パーティション移動など)により、ゾーン・マップの古いパーティションに属する既存のゾーンは廃止とされますが、新しいパーティションに属するゾーンは、ゾーン・マップがリフレッシュされるまで計算されません。ゾーン・マップがリフレッシュされているかどうかに関係なく、Oracle Databaseはデータ移動操作後も、プルーニングのためのゾーン・マップを使用し続けます。ゾーン・マップにREFRESH ON DATA MOVEMENTオプションが付けられている場合、Oracle Databaseはデータ移動操作の終了時にリフレッシュを実行します。

  • ディメンション表のデータ移動

    この操作は、ゾーン・マップに影響を及ぼしません。

  • ディメンション表に対するなんらかのDML

    この操作はゾーン・マップ全体を失効させるため、完全リフレッシュが必要になります。ただし、1つ例外があります。それが更新操作であり、更新された列群がゾーン・マップによって参照されない場合、影響はありません。

  • ディメンション表への直接ロード

    この操作はゾーン・マップ全体を失効させます。ゾーン・マップに対してREFRESH ON LOADオプションが指定されている場合、Oracle Databaseはロード操作の直後にゾーン・マップ・リフレッシュを実行します。

  • ファクト表またはディメンション表へのDDL

    DDL操作時に、ゾーン・マップは失効不明(つまり「失効」が'unknown'に設定される)、要コンパイル(つまり、compile_state'needs_compileに設定される)とマークされます。この状態では、Oracle Databaseはプルーニングでゾーン・マップを使用しません。ただし、DDL操作の後でゾーン・マップを初めて使用するときにOracle Databaseはゾーン・マップをコンパイルし、その結果に基づいて、無効および失効の状態を適切に設定します。たとえば、MIN/MAX集計がゾーン・マップに格納されている列をDDL操作が削除した場合、ゾーン・マップのコンパイルは失敗するため、ゾーン・マップのcompile_state'compilation error'に設定され、「失効」は'unknown'のまま、「無効」は'yes'に設定されます。

14.3 ゾーン・マップのリフレッシュと失効

実表のデータが変更されると、Oracle Databaseはゾーン・マップを失効とマークするか、ゾーン・マップ内の個別のゾーンを失効とマークします。失効したゾーン・マップはプルーニングで使用されませんが、失効したゾーンがあるゾーン・マップはまだプルーニングで使用されます。ゾーン・マップをリフレッシュしてゾーンを更新し、プルーニングで使用できるようにする必要があります。

この項では、次の項目について説明します。

14.3.1 ゾーン・マップの失効について

ゾーン・マップが基づいている表のデータが変更された場合、変更された行に対応するゾーンは失効とマークされます。ゾーン・マップをリフレッシュしてゾーンを最新にする必要があります。

ファクト表のパーティション内の行が更新された場合、ゾーンに対応するパーティション表内の行は、更新のため、失効とマークされます。これにより集計パーティション・レベルの情報は自動的に無効になり、プルーニングはゾーン・レベルでのみ可能になります。この特定のパーティションに対応するゾーン・マップ内の行も、更新のため、失効とマークされます。

これは図14-1に、P2Z4における更新で示されており、対応するZ4は失効とマークされます。ただし、ゾーン・マップがまだ使用可能である点に注意してください。ゾーン・マップが部分的に失効しているかぎり、Z4に対応する表データは常に読み取られます(Z4でプルーニングは実行されません)。

図14-1 部分的に失効しているゾーン・マップ

図14-1の説明が続きます
「図14-1 部分的に失効しているゾーン・マップ」の説明

ディメンション表がファクト表に追加されると、ステータスは図14-2に似たものになります。

図14-2 ディメンション表を伴うゾーン・マップ

図14-2の説明が続きます
図14-2「ディメンション表を伴うゾーン・マップ」の説明

ディメンション表に対してなんらかのDMLが実行された場合、図14-3に示されているように、ゾーン・マップは完全に失効します。ゾーン・マップが完全に失効するため、完全にリフレッシュされるまで、プルーニングで使用できません。ゾーン・マップをリフレッシュするには、ALTER MATERIALIZED ZONEMAP文のREBUILDオプションを使用します。

図14-3 ディメンション表を伴うゾーン・マップと失効

図14-3の説明が続きます
図14-3「ディメンション表を伴うゾーン・マップと失効」の説明

14.3.2 ゾーン・マップのリフレッシュについて

Oracle Databaseでは、基礎になる表が変更された後、リフレッシュしてゾーン・マップをメンテナンスする必要があります。ゾーン・マップで使用されるリフレッシュ方法は、完全リフレッシュまたは増分リフレッシュです。REFRESH COMPLETE句を使用して指定される完全リフレッシュには、ゾーン・マップ内のすべてのゾーンの再構築が必要です。大量のデータを処理する必要があるため、完全リフレッシュには時間がかかります。REFRESH FAST句を使用して指定される増分リフレッシュは、最後のリフレッシュ以後に発生した変更のみを処理します。この方法では、ゼロから再構築せずにゾーン・マップをリフレッシュできます。ゾーン・マップはマテリアライズド・ビューを使用して内部的に実装されますが、ゾーン・マップの高速リフレッシュの実行には、実表上のマテリアライズド・ビュー・ログは必要ありません。

リフレッシュ・モードは、ゾーン・マップのリフレッシュをトリガーする操作を指定します。次のいずれかのリフレッシュ・モードを使用します。

  • ON COMMIT

    実表に対する変更のコミット時にゾーン・マップがリフレッシュされます。

  • ON DEMAND

    DML操作またはパーティション・メンテナンス操作の後、手動でゾーン・マップをリフレッシュする必要があります。

  • ON DATA MOVEMENT

    実表上でデータ移動操作が実行されたときにゾーン・マップがリフレッシュされます。

  • ON LOAD

    実表上で直接パス挿入操作が実行されたときにゾーン・マップがリフレッシュされます。

  • ON LOAD DATA MOVEMENT

    実表上で直接パス挿入操作またはデータ移動操作が実行されたときにゾーン・マップがリフレッシュされます。これはデフォルトです。

デフォルトでは、ゾーン・マップはロード時およびデータ移動時にリフレッシュされます。このデフォルトをオーバーライドするには、ゾーン・マップの作成または変更時に、次のリフレッシュ・モードの1つを指定します: ON COMMITON LOADON DATA MOVEMENTまたはON LOAD

14.3.3 ゾーン・マップのリフレッシュ

REFRESHオプションを指定しないでゾーン・マップを作成した場合、Oracle Databaseはデフォルトで、直接ロードの後、および特定のデータ移動操作の後に、ゾーン・マップのメンテナンスを実行します。例外は、DML操作(たとえば削除、挿入および更新)です。これらの操作の場合、Oracle Databaseは、ゾーン・マップ、またはゾーン・マップ内の一部のゾーンを、適切に失効とマークします。ゾーン・マップのリフレッシュ・メンテナンスを手動で制御するには、REFRESH ON DEMANDオプションを指定する必要があります。

次のコマンドは、リフレッシュ・メンテナンスが無効化されたゾーン・マップを作成します。この場合、基礎になる表が変更された後、ゾーン・マップを手動でリフレッシュする必要があります。

CREATE MATERIALIZED ZONEMAP sales_zmap 
      ON sales (time_id, cust_id)
      REFRESH ON DEMAND;

Oracle Databaseには、ゾーン・マップをリフレッシュする次の2つの方法があります。

14.3.3.1 ALTER MATERIALIZED ZONEMAPコマンドを使用したゾーン・マップのリフレッシュ

ゾーン・マップをリフレッシュするには、ALTER MATERIALIZED ZONEMAPコマンドのREBUILDオプションを使用します。

次のコマンドは、ゾーン・マップの完全リフレッシュを実行します。

ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD COMPLETE;

次のコマンドは、ゾーン・マップが完全に失効しているか、使用不能とマークされている場合に、完全リフレッシュを実行します。それ以外の場合は、増分(高速)リフレッシュが実行されます。

ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD;

関連項目:

ゾーン・マップ・リフレッシュの構文については、『Oracle Database SQL言語リファレンス』を参照してください。

14.3.3.2 DBMS_MVIEWパッケージを使用したゾーン・マップのリフレッシュ

DBMS_MVIEWパッケージのREFRESHプロシージャを使用してゾーン・マップをリフレッシュできます。

DBMS_MVIEW.REFRESHプロシージャを使用する場合、Oracle Databaseは、次に示すようなゾーン・マップのrefresh_methodパラメータに指定されている値に応じてリフレッシュを実行します。

  • C: 完全リフレッシュを実行します。

  • F - 高速リフレッシュを実行します。高速リフレッシュができない場合は、エラーが発行されます。

  • ? - 可能な場合は高速リフレッシュを実行します。それ以外の場合は完全リフレッシュを実行します。

    値が指定されない場合、これがデフォルトとして使用されます。

REFRESHプロシージャの使用例を次に示します。

EXECUTE DBMS_MVIEW.REFRESH('sales_zmap','C');

14.4 ゾーン・マップを使用したプルーニングの実行

ゾーン・マップの主要な利点は、表スキャンのI/O削減です。プルーニングは、レコードの自然な場所に関する情報を活用して不必要なI/Oを回避します。SQL文に、ゾーン・マップで追跡される列にある述語が含まれる場合、データベースは各ゾーンについて述語値を最小値および最大値と比較して、表スキャン時にブロックのどのゾーンを読み取る、またはスキップするべきかを決定します。

ゾーン・マップ・プルーニングの候補には、次の述語が含まれます。

  • 関係述語=、<=、<、>、>=

  • (column_name relational_predicate constant形式のもの。たとえば、WHERE country_name='US'WHERE country_name=:name)

  • INリスト(たとえば、WHERE product_name IN ('a','b'))

  • 接尾辞%が付けられたLIKE述語(たとえば、company_name LIKE 'ORA%')

この項では、次の項目について説明します。

14.4.1 ゾーン・マップを使用したプルーニングの実行方法

この項では、次の例を使用して、ゾーン・マップと属性クラスタリングでプルーニングがどのように実行されるかを説明します。

14.4.1.1 ゾーン・マップを使用した表のプルーニング

この例は、述語が定数を含む問合せにおいてデータをプルーニングできるゾーン・マップの作成を示しています。表14-1に示すlineitem表は、次の文を使用して作成されます。

CREATE TABLE lineitem 
  ( orderkey      NUMBER 
  , shipdate      DATE
  , receiptdate   DATE
  , destination   VARCHAR2(50)
  , quantity      NUMBER);

この表には、1ブロックにつき2行のデータ・ブロックが4つ含まれると想定します。表14-1は、表の8つの行を示しています。

表14-1 lineitem表のデータ・ブロック

ブロック orderkey shipdate receiptdate destination quantity

1

1

1-1-2011

1-10-2011

San_Fran

100

1

2

1-2-2011

1-10-2011

San_Fran

200

2

3

1-3-2011

1-5-2011

San_Fran

100

2

4

1-5-2011

1-10-2011

San_Diego

100

3

5

1-10-2011

1-15-2011

San_Fran

100

3

6

1-12-2011

1-16-2011

San_Fran

200

4

7

1-13-2011

1-20-2011

San_Fran

100

4

8

1-15-2011

1-30-2011

San_Jose

100

次に、CREATE MATERIALED ZONEMAP文を使用して、lineitem表上にゾーン・マップを作成します。

CREATE MATERIALIZED ZONEMAP lineitem_zmap 
     ON lineitem (orderkey, shipdate, receiptdate);

各ゾーンには2つのブロックが含まれ、orderkeyshipdateおよびreceiptdate列の最小値と最大値が格納されます。表14-2は、ゾーン・マップを示しています。

表14-2 lineitem表のゾーン・マップ

ブロックの範囲 min orderkey max orderkey min shipdate max shipdate min receiptdate max receiptdate

1-2

1

4

1-1-2011

1-5-2011

1-9-2011

1-10-2011

3-4

5

8

1-10-2011

1-15-2011

1-15-2011

1-30-2011

次の問合せを実行すると、データベースはゾーン・マップを読み、日付1-3-2011が日付の最小値と最大値の間にある、ブロック1および2のみをスキャンします。

SELECT * FROM lineitem WHERE shipdate = '1-3-2011';
14.4.1.2 ゾーン・マップと属性クラスタリングを使用したパーティション表のプルーニング

この次の文は、パーティション表上に、属性クラスタリングを伴うゾーン・マップを作成します。

CREATE TABLE sales
(
   prod_id        NUMBER NOT NULL,
   cust_id        NUMBER NOT NULL,
   time_id        DATE NOT NULL,
   channel_id     NUMBER NOT NULL,
   promo_id       NUMBER NOT NULL,
   quantity_sold  NUMBER(10,2) NOT NULL,
   amount_sold    NUMBER(10,2)
)
CLUSTERING sales JOIN products ON (sales.prod_id = products.prod_id)
   BY LINEAR ORDER (products.prod_id)
   WITH MATERIALIZED ZONEMAP (sales_zmap)
PARTITION BY HASH (amount_sold)
     ( PARTITION p1, PARTITION p2);

図14-4は、パーティション表salesのゾーン・マップの作成を示しています。5つのゾーンの各々について、ゾーン・マップには、ゾーン・マップで追跡される列の最小値と最大値が格納されます。述語が各ゾーンに格納された列の最小値と最大値の間にない場合、そのゾーンを読み取る必要はありません。一例として、ゾーンZ4が列prod_idの最小値10と最大値100を追跡している場合、このゾーンには述語prod_id = 200に一致するレコードは決して存在しないため、ゾーンZ4は読み取られません。

パーティション表では、パーティション上でもゾーン・レベル上でもプルーニングが発生することがあります。ゾーン・マップの集計パーティション・レベルの情報により、指定された述語の組合せに対して、一致するデータの可能性が否定される場合、パーティション全体がプルーニングされます。それ以外の場合は、ゾーン・レベルごとにパーティションのプルーニングが発生します。

図14-4 パーティション・ファクト表のゾーン・マップ

図14-4の説明が続きます
図14-4「パーティション・ファクト表のゾーン・マップ」の説明

14.4.2 例: ゾーン・マップと属性クラスタリングによるプルーニングの実行

この項では、ゾーン・マップと属性クラスタリングを使用したプルーニングの実行の例を示します。例は、例14-16のように作成されたmy_sales表に基づきます。

例14-16 my_sales表の作成

my_sales表は、ゾーン・マップを含む、結合属性クラスタリングされた表です。SHスキーマのsales表に基づき、次の文を使用して作成されています。

CREATE TABLE my_sales
PARTITION BY LIST (channel_id)
 (PARTITION mysales_chan_c VALUES ('C'),
  PARTITION mysales_chan_i VALUES ('I'),
  PARTITION mysales_chan_p VALUES ('P'),
  PARTITION mysales_chan_s VALUES ('S'),
  PARTITION mysales_chan_t VALUES ('T'))
CLUSTERING
  my_sales JOIN customers ON (my_sales.cust_id = customers.cust_id)
  BY INTERLEAVED ORDER ((my_sales.time_id),
                        (customers.country_id, 
                         customers.cust_state_province, 
                         customers.cust_city))
  WITH MATERIALIZED ZONEMAP (mysales_zmap)
AS SELECT * FROM sales;

この項では、次の項目について説明します。

14.4.2.1 例:パーティションと表スキャン・プルーニング

この例は、ゾーン・マップがゾーンとパーティション(または、コンポジット・パーティション表内のサブパーティション)をどのようにプルーニングできるかを示しています。

  1. my_sales表を作成します。例14-16には、この表を作成するために使用する構文が含まれています。
  2. 次の文を使用して、customersディメンションに結合されているmy_sales表を問合せます。
    SELECT c.cust_city, SUM(quantity_sold)
       FROM   my_sales s, customers c
       WHERE  s.cust_id = c.cust_id 
          AND    c.country_id = 'US' 
          AND    c.cust_state_province = 'CA' 
          AND    s.promo_id < 50
       GROUP BY c.cust_city;
    
  3. 次の文を使用して計画を表示します。
    SELECT * 
    FROM TABLE(dbms_xplan.display_cursor(FORMAT => 'BASIC PREDICATE PARTITION'));
    
    -------------------------------------------------------------------------
    | Id  | Operation                           | Name      | Pstart| Pstop |
    -------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                    |           |       |       |
    |   1 |  HASH GROUP BY                      |           |       |       |
    |*  2 |   HASH JOIN                         |           |       |       |
    |   3 |    JOIN FILTER CREATE               | :BF0000   |       |       |
    |*  4 |     TABLE ACCESS FULL               | CUSTOMERS |       |       |
    |   5 |    JOIN FILTER USE                  | :BF0000   |       |       |
    |   6 |     PARTITION LIST ITERATOR         |           |KEY(ZM)|KEY(ZM)|
    |*  7 |      TABLE ACCESS FULL WITH ZONEMAP | MY_SALES  |KEY(ZM)|KEY(ZM)|
    -------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    
    PLAN_TABLE_OUTPUT
    -------------------------------------------------------------------------
       2 - access("S"."CUST_ID"="C"."CUST_ID")
       4 - filter(("C"."CUST_STATE_PROVINCE"='CA' AND
          "C"."COUNTRY_ID"='US'))
       7 - filter((SYS_ZMAP_FILTER('/* ZM_PRUNING */ SELECT "ZONE_ID$",
          CASE WHEN BITAND(zm."ZONE_STATE$",1)=1 THEN 1 ELSE CASE WHEN
          (zm."MIN_2_COUNTRY_ID" > :1 OR zm."MAX_2_COUNTRY_ID" < :2 OR
          zm."MIN_3_CUST_STATE_PROVINCE" > :3 OR zm."MAX_3_CUST_STATE_PROVINCE" <
          :4) THEN 3 ELSE 2 END END FROM "SH"."MYSALES_ZMAP" zm WHERE
          zm."ZONE_LEVEL$"=0 ORDER BY zm."ZONE_ID$"',SYS_OP_ZONE_ID(ROWID),'US','U
          S','CA','CA')<3 AND "S"."PROMO_ID"<50 AND
          SYS_OP_BLOOM_FILTER(:BF0000,"S"."CUST_ID")))
    

    7行目は、ゾーン・マップが使用されることを示します。ゾーン・マップ・パーティション・リスト・イテレータ“KEY(ZM)"に注意してください。

14.4.2.2 例: ゾーン・マップ結合プルーニング

この例は、ゾーン・マップと属性クラスタリングを使用する結合プルーニングを示しています。ディメンションの主キーがディメンション階層の値から構成されている場合、対応する外部キーでファクト表をクラスタリングすれば十分です。この例では、times.time_idが(calendar_year, calendar_month_number, day_number_in_month)のように構成されています。このため、time_idは、カレンダ時間階層および財務時間階層に変換されます。財務階層とカレンダ階層のいずれかについて述語が存在する場合、timesmy_salesの間の結合をプルーニングすることができます。

  1. my_sales表を作成します。例14-16には、この表を作成するために使用する構文が含まれています。
  2. 次の文を使用して、timesに結合されたmy_sales表を問い合せます。
    SELECT SUM(quantity_sold) 
    FROM   my_sales s, times tWHERE  s.time_id = t.time_id AND t.calendar_year = '1999';
    
  3. 次の文を使用して計画を表示します。
    SELECT * 
    FROM TABLE(dbms_xplan.display_cursor(FORMAT => 'BASIC PREDICATE PARTITION'));
    
    ---------------------------------------------------------------------------
    | Id  | Operation                               | Name    | Pstart| Pstop |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                        |         |       |       |
    |   1 |  SORT AGGREGATE                         |         |       |       |
    |*  2 |   HASH JOIN                             |         |       |       |
    |   3 |    JOIN FILTER CREATE                   | :BF0000 |       |       |
    |*  4 |     TABLE ACCESS FULL                   | TIMES   |       |       |
    |   5 |    JOIN FILTER USE                      | :BF0000 |       |       |
    |   6 |     PARTITION LIST ALL                  |         |     1 |     5 |
    |*  7 |      TABLE ACCESS FULL WITH ZONEMAP     | MY_SALES|     1 |     5 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
    PLAN_TABLE_OUTPUT
    ----------------------------------------------------
       2 - access("S"."TIME_ID"="T"."TIME_ID")
       4 - filter("T"."CALENDAR_YEAR"=1999)
       7 - filter((SYS_ZMAP_FILTER('/* ZM_PRUNING */ SELECT "ZONE_ID$",
          CASE WHEN BITAND(zm."ZONE_STATE$",1)=1 THEN 1 ELSE CASE WHEN
          ((ORA_RAWCOMPARE(zm."MIN_1_TIME_ID",:1,8)>0 OR
          ORA_RAWCOMPARE(zm."MAX_1_TIME_ID",:2,8)<0)) THEN 3 ELSE 2 END END FROM
          "SH"."MYSALES_ZMAP" zm WHERE zm."ZONE_LEVEL$"=0 ORDER BY
          zm."ZONE_ID$"',SYS_OP_ZONE_ID(ROWID),SYSVARCOL,SYSVARCOL)<3 AND
          SYS_OP_BLOOM_FILTER(:BF0000,"S"."TIME_ID")))
    

    7行目は、一致するtime_idゾーンを結合して、ゾーン・マップを使用していることを示します。

14.5 ゾーン・マップ情報の表示

ゾーン・マップとメジャーについての情報は、データ・ディクショナリ・ビューに格納されます。

この項では、次の項目について説明します。

14.5.1 データベース内ゾーン・マップの詳細表示

データベース内のゾーン・マップに関する情報を表示するには、次のデータ・ディクショナリ・ビューの1つを使用します。

  • DBA_ZONEMAPS: データベース内のすべてのゾーン・マップを表示

  • ALL_ZONEMAPS: ユーザーにアクセスできるゾーン・マップを表示

  • USER_ZONEMAPS: ユーザーが所有するゾーン・マップを表示

次の問合せは、名前、実表、タイプ、リフレッシュ・モードおよび現在のユーザーが所有するゾーン・マップの失効を表示し、ゾーン・マップが属性クラスタリングとともに作成されているかどうかを示します。

SELECT zonemap_name,fact_table,hierarchical,with_clustering,refresh_mode,stale 
       FROM USER_ZONEMAPS;

ZONEMAP_NAME    FACT_TABLE  HIERARCHICAL  WITH_CLUSTERING REFRESH_MODE      STALE
------------    ----------  ------------  --------------- ------------      -----
ZMAP$_MY_SALES  MY_SALES      NO          YES             LOAD DATAMOVEMENT   NO

次の問合せは、ユーザーにアクセスできるすべてのゾーン・マップのステータスを表示します。PRUNINGがDISABLEDのゾーン・マップは、I/Oプルーニングで使用されません。無効とマークされているゾーン・マップは、基礎になる実表の構造が変更しているため、再コンパイルする必要があります。

SQL> SELECT zonemap_name,pruning,refresh_method,invalid,complie_state
    FROM all_zonemaps;

ZONEMAP_NAME     PRUNING    REFRESH_METHOD INVALID  UNUSABLE   COMPILE_STATE
------------    ---------   -------------- -------  ------     -------------
SALES_ZMAP       ENABLED    FORCE           NO      NO         VALID
ZMAP$_MY_SALES   DISABLED   FORCE           NO      NO         VALID

14.5.2 ゾーン・マップのメジャーの表示

ゾーン・マップ内のメジャーに関する情報を表示するには、次のビューの1つを使用します。

  • DBA_ZONEMAP_MEASURES: データベース内のすべてのゾーン・マップのメジャーを表示

  • ALL_ZONEMAP_MEASURES: ユーザーにアクセスできるゾーン・マップのメジャーを表示

  • USER_ZONEMAP_MEASURES: ユーザーが所有するゾーン・マップを表示

次の問合せは、ゾーン・マップ、メジャー、および現在のユーザーにアクセスできる各ゾーンについて最小値/最大値がメンテナンスされている列を表示します。

SELECT zonemap_name, measure, agg_function
FROM ALL_ZONEMAP_MEASURES;

ZONEMAP_NAME      MEASURE                         AGG_FUNCTION
---------------   --------------------------      -------------
ZMAP$_MY_SALES   "SH"."MY_SALES"."PROD_ID"        MAX
ZMAP$_MY_SALES   "SH"."MY_SALES"."PROD_ID"        MIN
ZMAP$_MY_SALES   "SH"."MY_SALES"."CUST_ID"        MAX
ZMAP$_MY_SALES   "SH"."MY_SALES"."CUST_ID"        MIN