ゾーン・マップは、表に対して作成できる、独立したアクセス構造です。表スキャンおよび索引スキャンにゾーン・マップを使用すると、表列上の述語に基づいて、表のディスク・ブロックや、パーティション表の完全なパーティションをプルーニングできる可能性があります。ゾーン・マップは、属性クラスタリングの有無にかかわらず使用できます。
この章の内容は次のとおりです。
ゾーン・マップは表に対して作成される独立したアクセス構造で、表のゾーンに関する情報が格納されます。ゾーン・マップを使用すると、表列上の述語に適合しないデータ・ブロックをデータベースがプルーニングできます。ゾーンとは、ディスク上で連続している一群のデータ・ブロックです。
従来のゾーン・マップは、ディスク・ユニット、ブロックまたはエクステントごとに表内の列の最小値と最大値を格納します。問合せがクラスタリング列を修飾する場合、I/Oプルーニングが発生します。Oracle Databaseのゾーン・マップは、一定範囲のブロック(ゾーンと呼ばれます)について、列の最小値と最大値を格納します。ファクト表がディメンション表との外部結合を介してディメンション属性により属性クラスタリングされていれば、クラスタリングされたファクト表の述語に基づくI/Oプルーニングの実行に加え、ゾーン・マップはディメンション表の述語上でもプルーニングします。
1つの表につき最大1つのゾーン・マップを定義できます。パーティション表の場合、すべてのパーティション(およびサブパーティション)について1つのゾーン・マップが存在します。パーティション表のゾーン・マップは、ゾーンごと、パーティションごと、サブパーティションごとの最小値と最大値を追跡します。表にディメンション表との外部結合がある場合、ゾーン・マップ定義にディメンション列の最小値と最大値を含めることができます。
この項には次のトピックが含まれます:
ゾーン・マップは、粗い索引構造のようなものです。ただし、索引とは次のような根本的な違いがあります。
ゾーン・マップには、行ごとではなくゾーンごとの情報が格納されます。このため、索引よりはるかにコンパクトです。
索引はDML処理との同期を維持しますが、ゾーン・マップは、そのようにアクティブには管理されません。このため、たとえゾーン・マップにREFRESH
ON
COMMIT
オプションが付けられていても、コミットまたはロールバックが発生するまで、トランザクション範囲内では失効していることがあります。
ゾーン・マップには、あるゾーンに関する失効した情報と、残りのゾーンに関する新しい情報が混在することがありますが、その場合もOracle Databaseでは、ファクト表のスキャン時に、そのゾーン・マップを使用してI/Oプルーニングを実行します。
属性クラスタリングは、ゾーン・マップにとって必須の前提条件ではありません。ゾーン・マップは、属性クラスタリングの有無にかかわらず使用できます。このため、ゾーン・マップがなくても属性クラスタリングを指定でき、クラスタリングがなくても表上でゾーン・マップを作成できます。
データ・ウェアハウジング環境では、ETL処理のデータを合理的にクラスタリングしているのが普通です(たとえば、時間列や地理的リージョンによるクラスタリング)。クラスタリングにより、列の最小値と最大値が、属性クラスタリングされた表内の連続的なデータ・ブロックと相関する傾向が高まるため、ゾーン・マップを使用するプルーニングの効率が向上します。ゾーン・マップを使用すると、属性クラスタリングにより実行されるデータの順序付けを利用できるため、プルーニングが効率化します。表スキャンと索引スキャンの際(たとえば、rowidによるフェッチ)、ゾーン・マップを使用すると、表列の述語に適合しないデータ・ブロックもプルーニングできます。
関連項目:
属性クラスタリングの詳細は、属性クラスタリングについてを参照してください。
基本的なゾーン・マップは単一の表の上で定義され、この表の一部の列の最小値と最大値を保持します。
結合ゾーン・マップは、1つ以上の別の表への外部結合を持っており、その別の表内の一部の列の最小値と最大値を保持している表の上で定義されます。これらの結合条件はマスターと詳細の関係でも、ファクト表とディメンション表の間のスター・スキーマでも一般的です。
スター・クエリーの場合、複数のディメンション表が、ファクト表とのPK-FK関係を介して結合されます。ここで、結合ゾーン・マップは、ファクト表のゾーンに対応するディメンション表の列の最小値と最大値を維持します。
表または表パーティションの順次スキャンまたは索引スキャン時のI/Oを削減
ゾーン・マップ列がパーティション化キーと相関している場合に、パーティション表やコンポジット・パーティション表の非キー列に基づくパーティション・プルーニングが可能
インターリーブ順序による属性クラスタリングで、クラスタリング列のサブセットにおけるI/O削減を可能にします。
索引の使用に関連する記憶域コストが不要
関連項目:
『Oracle Database SQL言語リファレンス』
表スキャンが、使用頻度の高い述語を使用して実行される
ゾーン・マップを使用すると、列述語によって除外されたゾーンをOracle Databaseがスキャンせずにすみます。
結合が、ディメンション階層列上で使用頻度の高い述語を使用して、ファクト表とディメンション表の間で定義される
ファクト表の行を、属性値上の述語によって除外されるゾーンをプルーニングしつつ、ディメンション属性値により順序付けることができます。
パーティション表内の列に、パーティション・キーと相関する値が含まれる
これにより、非キー列に基づくパーティション・プルーニングが容易になります。たとえば、日付でパーティション化されている表には、パーティション・キーとよく相関する他の日付列や、時間の経過に応じて変化または循環する連続値を含む列がしばしばあります。
データ・クラスタリングがゾーン・マップ列の値に対して実行される
属性クラスタリングは、特にこの目的のために設計されています。あるいは、データに内在する順序を利用するのが適切です(たとえば、順次的にロードされる、時間に基づく列値や、ロード時にソートされるデータ)。
頻度が高くカーディナリティが低い索引範囲スキャンが、表の上で実行される
属性クラスタリングを単独で使用して、圧縮係数を改善できます。ゾーン・マップを使用すると、除外されたゾーンからの参照をプルーニングすることによって、索引スキャンの効率を改善できます。あるいは、ゾーン・マップを索引のかわりに使用できます。
ゾーン・マップは表に基づいているため、基礎になる表に対する変更はなんであれ、ゾーン・マップの状態に影響します。表の上で実行される操作により異なりますが、ゾーン・マップの一部またはすべてのゾーンが影響を受けます。基礎になる表の変更により影響がおよぶゾーン・マップにはメンテナンスが必要です。
ゾーン・マップのメンテナンスは、次のうち1つ以上の作業で構成されます。
影響を受けるゾーン・マップの有効性チェック
影響を受けるゾーンの失効追跡
影響を受ける失効済ゾーン・マップのリフレッシュ(ゾーン・マップに対して設定されているリフレッシュ・モードにより異なる)
ゾーン・マップが基づいている実表の構造が変更された場合(たとえば、最小値と最大の値がゾーン・マップによって維持されている表列が削除されたなどの場合)、ゾーン・マップは無効になります。無効なゾーン・マップは問合せで使用されず、そのゾーン・マップはOracle Databaseではメンテナンスされません。ただし、ゾーン・マップと関連していない実表の構造が変更された場合(たとえば、表に新規の列が追加された場合など)、ゾーン・マップは有効なままですが、コンパイルが必要です。Oracle Databaseは、それ以降の操作(問合せによるゾーン・マップの使用など)の際に、ゾーン・マップを自動的にコンパイルします。または、ALTER MATERIALIZED ZONEMAP
コマンドのCOMPILE
句を使用してゾーン・マップをコンパイルすることもできます。
関連項目:
基礎になる表のデータが変更された場合、その変化の影響を受けるゾーンは「失効」とマークされます。失効したゾーン・マップでは、データだけは最新ではありませんが、定義はまだ有効です。Oracle Databaseは、様々なタイプの操作による、基礎になる表上でのゾーン・マップの失効を自動的に追跡します。基礎になる表の上で実行される操作のタイプに応じて、Oracle Databaseは、ゾーン・マップ全体を失効とマークするか、ゾーン・マップ内の一部のゾーンのみを失効とマークします。
この項には次のトピックが含まれます:
ゾーン・マップのメンテナンスが必要になるのは、基礎になる表の1つ以上に対して次の操作が行われる場合です。
DML(挿入、削除、更新、従来型ロード)。
直接パス挿入およびロード。
パーティションのメンテナンス操作(MOVE
、SPLIT
、MERGE
、DROP
、TRUNCATE
およびEXCHANGE
)、表データの移動、および表のオンライン再定義。
前述の操作の影響を受けたゾーン・マップをOracle Databaseが自動的にリフレッシュするかどうかは、ゾーン・マップ・リフレッシュ・モードにより決定されます。
Oracle Databaseでは、次のものに影響を受けるゾーン・マップについて自動リフレッシュが実行されます。
リフレッシュ・モードがREFRESH ON COMMIT
の場合、DML操作。REFRESH ON COMMIT
モードのゾーン・マップは、トランザクション的には最新のままです。リフレッシュは、トランザクションがコミットされたときに実行されます。
リフレッシュ・モードがREFRESH ON LOAD
の場合、直接パス挿入またはロード。
REFRESH ON LOAD
で構成されているゾーン・マップは、基礎になる表の上でのDMLまたはPMOP操作により失効することがあります。
リフレッシュ・モードがREFRESH ON DATA MOVEMENT
である場合、PMOP(MOVE
、SPLIT
、MERGE
、DROP
)または表の移動。
REFRESH ON DATA MOVEMENT
で構成されているゾーン・マップは、DML、直接パス挿入またはロード、PMOP(TRUNCATE
、EXCHANGE
)または基礎になる表のオンライン再定義の後、失効することがあります。
リフレッシュ・モードがREFRESH ON DATA MOVEMENT
である場合の、直接パス挿入またはロード、PMOP(MOVE
、SPLIT
、MERGE
、DROP
)または表の移動。
REFRESH ON LOAD DATA MOVEMENT
で構成されているゾーン・マップは、DML、PMOP(TRUNCATE
、EXCHANGE
)または基礎になる表のオンライン再定義の後、失効することがあります。
リフレッシュ・モードがREFRESH ON DEMAND
の場合、Oracle Databaseは基礎になる表でのなんらかの操作に影響を受けるゾーン・マップを自動リフレッシュしません。REFRESH ON DEMAND
が設定されているゾーン・マップは、手動でリフレッシュする必要があります。
この項では、ゾーン・マップを含む一般的なタスクについて、次のように分けて説明します。
独自のスキーマのゾーン・マップを作成、変更または削除するには、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
権限を持っている必要があります。
ゾーン・マップは属性クラスタリングとともに表の上に作成できますが、ゾーン・マップは属性クラスタリングから独立しています。ゾーン・マップは、属性クラスタリングにかかわりなく、独立して作成できます。
ゾーン・マップが使用する記憶域の構造は、それが定義される表のデフォルト表領域に作成されます。
関連項目:
ゾーン・マップ作成の構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
ゾーン・マップの制限事項の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
この項には次のトピックが含まれます:
WITH MATERIALIZED ZONEMAP
副次句を使用して、ゾーン・マップを作成できます。表に属性クラスタリングを定義する場合、または、後でクラスタリング定義を変更する場合、この副次句を使用できます。
次のいずれかのトピックに説明されている手順を使用して、属性クラスタリングによるゾーン・マップを作成します。
関連項目:
属性クラスタリングの詳細は、属性クラスタリングを参照してください。
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_id
、prod_id
)上にゾーン・マップZMAP$_SALES
が作成されます。ここで、ZMAP$_SALES
は、Oracle Databaseによって自動的に生成されるゾーン・マップの名前です。ただし、インターリーブ属性クラスタリングによる結合ゾーン・マップの作成で説明するとおり、WITH MATERIALIZED ZONEMAP
に続けてカッコに入れることでゾーン・マップの名前を指定できます。
列cust_id
とprod_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が含まれるゾーンのみ読み取る必要があります。
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
の自然階層)、グループ内の列の順序は階層内のものに従う必要があります。これにより、ディメンション表に存在する階層に応じて、データが効果的にクラスタリングされます。
データベースに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;
表上にゾーン・マップを作成するには、CREATE MATERIALIZED ZONEMAP
コマンドを使用します。このゾーン・マップは属性クラスタリングから独立しています。これは、クラスタリングされた表にもクラスタリングされていない表にも作成できるということです。また、ゾーン・マップに使用される列の組合せは、属性クラスタリングに使用される列の組合せと同じでも異なっていてもかまいません。
ゾーン・マップを作成する場合、ゾーン・マップが基づく表の列を指定する必要があります。
次のいずれかのトピックに説明されている手順を使用して、属性クラスタリングから独立したゾーン・マップを作成します。
sales
表上の問合せで、顧客ID、製品ID、またはその2つの列の組合せがよく指定されると想定します。例13-1
に示すように、プルーニングが問合せを効率化できるように、sales表の顧客ID列と製品ID列の上にゾーン・マップを作成できます。
例13-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が指定されると、隣接するディスク・ブロック(ゾーン)の個別の範囲を特定します。このファンクションは、ゾーン・マップのパーティション・プルーニングと高速リフレッシュを実行して、パーティション・レベルで最小値と最大値の範囲を維持する助けになります。ゾーン・マップで使用する場合、隣接するデータ・ブロック群から単一のゾーンにすべての行をマップすると便利です。
sales
ファクトと複数のディメンションを含むデータ・ウェアハウスを想定します。大部分の問合せは、customers
表階層(cust_state_province, cust_city
)上の述語を持っています。例13-2に示すように、sales表ではインターリーブ順序を使用できます。
例13-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);
ALTER
MATERIALIZED
ZONEMAP
文を使用してゾーン・マップを変更できます。
例13-3 ゾーン・マップの使用不能化
次の文は、ゾーン・マップを使用不能にします。これは、問合せがこのゾーン・マップをもう使用せず、Oracle Databaseによるゾーン・マップのメンテナンスも行われないことを意味します。
ALTER MATERIALIZED ZONEMAP sales_zmap UNUSABLE;
例13-4 ゾーン・マップの完全リフレッシュの実行
次の文は、ゾーン・マップの完全リフレッシュを実行します。
ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD COMPLETE;
ゾーン・マップがそれ以前に使用不能とマークされている場合、再構築の過程で使用可能にされます。
例13-5 ゾーン・マップのリフレッシュ
次の文は、可能な場合、高速リフレッシュを実行します。それ以外の場合は完全リフレッシュを実行します。
ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD;
例13-6 ゾーン・マップのプルーニングの無効化
次の文はプルーニングを無効にします。これはパフォーマンス測定の際に必要になることがあります。
ALTER MATERIALIZED ZONEMAP sales_zmap DISABLE PRUNING;
例13-7 ゾーン・マップのプルーニングの有効化
次の文は、以前に無効化されている可能性があるゾーン・マップのプルーニングを有効化します。
ALTER MATERIALIZED ZONEMAP sales_zmap ENABLE PRUNING;
例13-8 ゾーン・マップのリフレッシュの無効化
次の文は、ロード時のリフレッシュとデータ移動をオフにし、それにより、ゾーン・マップがリフレッシュされる方法とタイミングを制御できるようにします。
ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON DEMAND;
例13-9 コミット時のゾーン・マップ・リフレッシュの有効化
次の文は、各トランザクションのコミット時におけるゾーン・マップのリフレッシュをオンにします。
ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON COMMIT;
関連項目:
ゾーン・マップ変更の構文については、『Oracle Database SQL言語リファレンス』を参照してください。
次のように、DROP MATERIALIZED ZONEMAP
文を発行することによってゾーン・マップを削除できます。
DROP MATERIALIZED ZONEMAP sales_zmap;
関連項目:
ゾーン・マップ削除の構文については、『Oracle Database SQL言語リファレンス』を参照してください。
ゾーン・マップが基づいている実表に関するDDL操作はすべて、ゾーン・マップのコンパイル状態に影響を及ぼします。このため、ゾーン・マップがまだ有効かどうか確認するには、ゾーン・マップを定義する問合せをコンパイルする必要があります。この動作はマテリアライズド・ビューと類似しています。それも実表で実行されるDDLの影響を受けるためです。Oracle Databaseは、DDL操作後、ゾーン・マップを初めて使用しようとするときにコンパイルします。ただし、次のようなDDL変更文を使用して、ゾーン・マップを明示的にコンパイルすることができます。
ALTER MATERIALIZED ZONEMAP sales_zmap COMPILE;
ゾーン・マップのコンパイル結果は、DDLによって実行された個別処理に応じて、有効か無効のいずれかです。たとえば、ファクト表に列を追加するためにDDLが実行された場合、ゾーン・マップはコンパイル後に有効になります。一方、定義問合せで参照された列を削除するためにDDLが実行された場合、ゾーン・マップはコンパイル後に無効になります。
注意すべきポイントは次のとおりです。
クラスタリング句に出現する列が削除されると、クラスタリングは削除されます。また、クラスタリングの一部として作成されたゾーン・マップがあれば、そのゾーン・マップも削除されます。
スター・スキーマからのディメンション表が削除され、それがファクト表上のクラスタリングに含まれていた場合、そのファクト表のクラスタリングは削除されます。また、クラスタリングの一部として作成されたゾーン・マップがあれば、そのゾーン・マップは削除されます。
ユーザーがクラスタリング句に含まれるディメンション表上の必須の主キーまたは一意キーを削除した場合、クラスタリングは無効にされます(一部のタイプのPMOPがそれ以降にロードまたはデータ移動操作を実行しても、データのクラスタリングが行われません)。
SQLワークロード全体または特定の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;
ヒントを使用して、個別のSQL文レベルでゾーン・マップの使用を制御できます。ゾーン・マップに対してプルーニングが無効にされている場合、ヒントを使用してゾーン・マップの使用を制御できないことに注意してください。プルーニングは有効なままにしておき、個別のSQL文で否定的なヒントを指定することで、ヒントを介してより細かく制御できます。
プルーニングによるゾーン・マップの使用を無効にするには、NO_ZONEMAP
ヒントを使用します。次の例は、データをプルーニングしますが、ゾーン・マップの使用を無効にします。
例13-10 スキャン・プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化
SELECT /*+ NO_ZONEMAP (S SCAN) */* FROM sales S WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';
例13-11 結合プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化
SELECT /*+ NO_ZONEMAP (S JOIN) */* FROM sales s WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';
例13-12 パーティション・プルーニング: NO_ZONEMAPヒントを使用したゾーン・マップの無効化
SELECT /*+ NO_ZONEMAP (S PARTITION) */* FROM sales S WHERE s.time_id BETWEEN '1-15-2008' AND '1-31-2008';
ゾーン・マップの作成時、または後でゾーン・マップ定義を変更するときに、ゾーン・マップをメンテナンスする方法を指定できます。ゾーン・マップ・メンテナンスに関する考慮事項を参照してください。
関連項目:
ゾーン・マップのメンテナンス方法を指定するには、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
文を使用します。
例13-13 データ移動時におけるゾーン・マップ・メンテナンスの有効化
次の文は、Oracle Databaseによる、データ移動操作時(たとえばMOVE
、SPLIT
、MERGE
およびDROP
)のゾーン・マップ・メンテナンスを有効にします。
ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON DATA MOVEMENT;
例13-14 直接パス・ロード時におけるゾーン・マップ・メンテナンスの有効化
次の文は、Oracle Databaseによる直接パス・ロード操作時(INSERT /*+ APPEND */
文など)のゾーン・マップ・メンテナンスを有効にします。
ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON LOAD;
例13-15 データの移動およびロード時におけるゾーン・マップ・メンテナンスの有効化
次の文は、Oracle Databaseによる、データ移動およびロード操作時のゾーン・マップ・メンテナンスを有効にします。
ALTER MATERIALIZED ZONEMAP sales_zmap REFRESH ON LOAD DATA MOVEMENT;
REFRESH ON LOAD DATA MOVEMENT
がデフォルトのオプションである点に注意してください。
ゾーン・マップのメンテナンスと失効の追跡に関する、注意が必要な問題のいくつかを次に示します。
ファクト表に対する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'
に設定されます。
実表のデータが変更されると、Oracle Databaseはゾーン・マップを失効とマークするか、ゾーン・マップ内の個別のゾーンを失効とマークします。失効したゾーン・マップはプルーニングで使用されませんが、失効したゾーンがあるゾーン・マップはまだプルーニングで使用されます。ゾーン・マップをリフレッシュしてゾーンを更新し、プルーニングで使用できるようにする必要があります。
この項には次のトピックが含まれます:
ゾーン・マップが基づいている表のデータが変更された場合、変更された行に対応するゾーンは失効とマークされます。ゾーン・マップをリフレッシュして最新にする必要があります。
ファクト表のパーティション内の行が更新された場合、ゾーンに対応するパーティション表内の行は、更新のため、失効とマークされます。これにより集計パーティション・レベルの情報は自動的に無効になり、プルーニングはゾーン・レベルでのみ可能になります。この特定のパーティションに対応するゾーン・マップ内の行も、更新のため、失効とマークされます。
これは図13-1に、P2
のZ4
における更新で示されており、対応するZ4
は失効とマークされます。ただし、ゾーン・マップがまだ使用可能である点に注意してください。ゾーン・マップが部分的に失効しているかぎり、Z4
に対応する表データは常に読み取られます(Z4
でプルーニングは実行されません)。
ディメンション表がファクト表に追加されると、ステータスは図13-2に似たものになります。
ディメンション表に対してなんらかのDMLが実行された場合、図13-3に示されているように、ゾーン・マップは完全に失効します。ゾーン・マップが完全に失効するため、完全にリフレッシュされるまで、プルーニングで使用できません。ゾーン・マップをリフレッシュするには、ALTER MATERIALIZED ZONEMAP
文のREBUILD
オプションを使用します。
Oracle Databaseでは、基礎になる表が変更された後、リフレッシュしてゾーン・マップをメンテナンスする必要があります。ゾーン・マップで使用されるリフレッシュ方法は、完全リフレッシュまたは増分リフレッシュです。REFRESH COMPLETE
句を使用して指定される完全リフレッシュには、ゾーン・マップ内のすべてのゾーンの再構築が必要です。大量のデータを処理する必要があるため、完全リフレッシュには時間がかかります。REFRESH FAST
句を使用して指定される増分リフレッシュは、最後のリフレッシュ以後に発生した変更のみを処理します。この方法では、ゼロから再構築せずにゾーン・マップをリフレッシュできます。ゾーン・マップはマテリアライズド・ビューを使用して内部的に実装されますが、ゾーン・マップの高速リフレッシュの実行には、実表上のマテリアライズド・ビュー・ログは必要ありません。
リフレッシュ・モードは、ゾーン・マップのリフレッシュをトリガーする操作を指定します。次のいずれかのリフレッシュ・モードを使用します。
ON COMMIT
実表に対する変更のコミット時にゾーン・マップがリフレッシュされます。
ON DEMAND
DML操作またはパーティション・メンテナンス操作の後、手動でゾーン・マップをリフレッシュする必要があります。
ON DATA MOVEMENT
実表上でデータ移動操作が実行されたときにゾーン・マップがリフレッシュされます。
ON LOAD
実表上で直接パス挿入操作が実行されたときにゾーン・マップがリフレッシュされます。
ON LOAD DATA MOVEMENT
実表上で直接パス挿入操作またはデータ移動操作が実行されたときにゾーン・マップがリフレッシュされます。これがデフォルトです。
デフォルトでは、ゾーン・マップはロード時およびデータ移動時にリフレッシュされます。このデフォルトをオーバーライドするには、ゾーン・マップの作成または変更時に、次のリフレッシュ・モードの1つを指定します: ON COMMIT
、ON LOAD
、ON DATA MOVEMENT
またはON LOAD
。
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つの方法があります。
ゾーン・マップをリフレッシュするには、ALTER MATERIALIZED ZONEMAP
コマンドのREBUILD
オプションを使用します。
次のコマンドは、ゾーン・マップの完全リフレッシュを実行します。
ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD COMPLETE;
次のコマンドは、ゾーン・マップが完全に失効しているか、使用不能とマークされている場合に、完全リフレッシュを実行します。それ以外の場合は、増分(高速)リフレッシュが実行されます。
ALTER MATERIALIZED ZONEMAP sales_zmap REBUILD;
関連項目:
ゾーン・マップ・リフレッシュの構文については、『Oracle Database SQL言語リファレンス』を参照してください。
DBMS_MVIEW
パッケージのREFRESH
プロシージャを使用してゾーン・マップをリフレッシュできます。
DBMS_MVIEW.REFRESH
プロシージャを使用する場合、Oracle Databaseは、次に示すようなゾーン・マップのrefresh_method
パラメータに指定されている値に応じてリフレッシュを実行します。
C: 完全リフレッシュを実行します。
F - 高速リフレッシュを実行します。高速リフレッシュができない場合は、エラーが発行されます。
? - 可能な場合は高速リフレッシュを実行します。それ以外の場合は完全リフレッシュを実行します。
値が指定されない場合、これがデフォルトとして使用されます。
REFRESH
プロシージャの使用例を次に示します。
EXECUTE DBMS_MVIEW.REFRESH('sales_zmap','C');
ゾーン・マップの主要な利点は、表スキャンの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%'
)
この項には次のトピックが含まれます:
この項では、次の例を使用して、ゾーン・マップと属性クラスタリングでプルーニングがどのように実行されるかを説明します。
この例は、述語が定数を含む問合せにおいてデータをプルーニングできるゾーン・マップの作成を示しています。表13-1
に示すlineitem表は、次の文を使用して作成されます。
CREATE TABLE lineitem ( orderkey NUMBER , shipdate DATE , receiptdate DATE , destination VARCHAR2(50) , quantity NUMBER);
この表には、1ブロックにつき2行のデータ・ブロックが4つ含まれると想定します。表13-1は、表の8つの行を示しています。
表13-1 lineitem表のデータ・ブロック
Block | 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つのブロックが含まれ、orderkey
、shipdate
およびreceiptdate
列の最小値と最大値が格納されます。表13-2は、ゾーン・マップを示しています。
表13-2 lineitem表のゾーン・マップ
Block Range | 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';
この次の文は、パーティション表上に、属性クラスタリングを伴うゾーン・マップを作成します。
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);
図13-4は、パーティション表sales
のゾーン・マップの作成を示しています。5つのゾーンの各々について、ゾーン・マップには、ゾーン・マップで追跡される列の最小値と最大値が格納されます。述語が各ゾーンに格納された列の最小値と最大値の間にない場合、そのゾーンを読み取る必要はありません。一例として、ゾーンZ4
が列prod_id
の最小値10と最大値100を追跡している場合、このゾーンには述語prod_id
=
200
に一致するレコードは決して存在しないため、ゾーンZ4
は読み取られません。
パーティション表では、パーティション上でもゾーン・レベル上でもプルーニングが発生することがあります。ゾーン・マップの集計パーティション・レベルの情報により、指定された述語の組合せに対して、一致するデータの可能性が否定される場合、パーティション全体がプルーニングされます。それ以外の場合は、ゾーン・レベルごとにパーティションのプルーニングが発生します。
この項では、ゾーン・マップと属性クラスタリングを使用したプルーニングの実行の例を示します。例は、例13-16
のように作成されたmy_sales表に基づきます。
例13-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;
この項には次のトピックが含まれます:
この例は、ゾーン・マップがゾーンとパーティション(または、コンポジット・パーティション表内のサブパーティション)をどのようにプルーニングできるかを示しています。
この例は、ゾーン・マップと属性クラスタリングを使用する結合プルーニングを示しています。ディメンションの主キーがディメンション階層の値から構成されている場合、対応する外部キーでファクト表をクラスタリングすれば十分です。この例では、times.time_id
が(calendar_year
, calendar_month_number
, day_number_in_month
)のように構成されています。このため、time_id
は、カレンダ時間階層および財務時間階層に変換されます。財務階層とカレンダ階層のいずれかについて述語が存在する場合、times
とmy_sales
の間の結合をプルーニングすることができます。
データベース内のゾーン・マップに関する情報を表示するには、次のデータ・ディクショナリ・ビューの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
ゾーン・マップ内のメジャーに関する情報を表示するには、次のビューの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