3.3 索引のパーティション化
索引のパーティション化には、パーティション表共通の推奨事項および考慮事項があります。
索引のパーティション化に関するルールは、表についてのルールと似ています。
-
次の項目に該当しないかぎり、索引のパーティション化が可能です。
-
索引がクラスタ索引である。
-
索引がクラスタ化表に定義されている。
-
-
次のように、パーティション索引および非パーティション索引は、パーティション表および非パーティション表に混在させることができます。
-
パーティション表にパーティション索引または非パーティション索引を定義できる。
-
非パーティション表にパーティション索引または非パーティション索引を定義できる。
-
-
非パーティション表のビットマップ索引は、パーティション化できません。
-
パーティション表のビットマップ索引は、ローカル索引にする必要があります。
ただし、パーティション索引はパーティション表よりも複雑です。パーティション索引には次の3つのタイプがあるためです。
-
ローカル同一キー索引
-
ローカル非同一キー索引
-
グローバル同一キー索引
Oracle Databaseでは、これら3つのタイプがすべてサポートされています。ただし、いくつかの制限があります。たとえば、パーティション表でローカル一意索引を作成する場合、キーを式にすることはできません。
次の内容について説明します。
関連項目:
DBA_INDEXES
、DBA_IND_PARTITIONS
、DBA_IND_SUBPARTITIONS
およびDBA_PART_INDEXES
ビューについては、『Oracle Databaseリファレンス』を参照してください。
3.3.1 ローカル・パーティション索引
ローカル索引の場合、特定の索引パーティションのキーはすべて、基礎となる表の1つのパーティションに格納されている行のみを参照します。
ローカル索引は、LOCAL
属性を指定することで作成されます。Oracleは、基礎となる表と同一レベルでパーティション化されるようにローカル索引を作成します。基礎となる表と同じ列で索引をパーティション化し、同じ数のパーティションまたはサブパーティションを作成して、基礎となる表の対応するパーティションと同じパーティション・バウンドを設定します。
また、Oracleは、基礎となる表のパーティションが追加、削除、マージまたは分割されたり、ハッシュ・パーティションやサブパーティションが追加または結合されたりした場合は、索引のパーティション化を自動的にメンテナンスします。これにより、索引のパーティションが表と同一レベルに保たれます。
パーティション列が索引列のサブセットを形成している場合は、ローカル索引をUNIQUE
として作成できます。この制限により、同一の索引キーを持つ行は同じパーティションにマップされることが保証され、一意性の違反を検出できるようになります。
ローカル索引には次のメリットがあります。
-
基礎となる表パーティションに対して
SPLIT
PARTITION
またはADD
PARTITION
以外のメンテナンス操作を実行する際、再作成する必要のある索引パーティションが1つで済みます。 -
パーティション表にローカル索引しかない場合、パーティションのメンテナンス操作にかかる時間はパーティションのサイズに比例します。
-
ローカル索引によって、パーティションの独立性がサポートされます。
-
ローカル索引では、履歴表の古いデータのロールアウト、新しいデータのロールインをスムーズに実行できます。
-
Oracleは、ローカル索引は基礎となる表と同一レベルでパーティション化されるという特性を利用して、より適切な問合せのアクセス計画を生成できます。
-
ローカル索引を使用すると、表領域の不完全リカバリ作業が簡素化されます。表のパーティションまたはサブパーティションをある時点までリカバリするには、対応する索引エントリも同じ時点までリカバリする必要があります。この処理は、ローカル索引を使用している場合にのみ行うことができます。ローカル索引を使用している場合は、対応する表と索引のパーティションまたはサブパーティションをリカバリできます。
次の内容について説明します。
関連項目:
DBMS_PCLXUTIL
パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください
3.3.1.1 ローカル同一キー索引
ローカル索引が同一キーになるのは、索引列の左プリフィックスでパーティション化され、サブパーティション化キーが索引キーに含まれる場合です。ローカル同一キー索引は、一意にも非一意にもできます。
たとえば、sales
表とそのローカル索引sales_ix
がweek_num
列でパーティション化されているとき、索引sales_ix
がローカル同一キーになるのは列week_num
およびxaction_num
に定義されている場合です。これに対して、索引sales_ix
が列product_num
に定義されている場合は、同一キーにはなりません。
図3-4に、ローカル同一キー索引の別の例を示します。
3.3.1.2 ローカル非同一キー索引
索引列の左プリフィックスでパーティション化されていないローカル索引は、非同一キー索引です。あるいは、索引キーにサブパーティション化キーが含まれない場合、ローカル索引は非同一キー索引です。
パーティション化キーが索引キーのサブセットでない場合、一意のローカル非同一キー索引は定義できません。
図3-5に、ローカル非同一キー索引の例を示します。
3.3.2 グローバル・パーティション索引
グローバル・パーティション索引では、特定の索引パーティションのキーが、複数の基礎となる表のパーティションまたはサブパーティションに格納されている行を参照する場合があります。
グローバル索引ではレンジ・パーティション化またはハッシュ・パーティション化が可能ですが、定義するパーティション表はどのタイプでもかまいません。グローバル索引は、GLOBAL
属性を指定することで作成されます。データベース管理者は、グローバル索引の作成時に最初のパーティション化を定義して、それ以降はパーティション化のメンテナンスを行う必要があります。索引パーティションは、必要に応じてマージまたは分割できます。
通常、グローバル索引を、基礎となる表と同一レベルでパーティション化することはありません。基礎となる表と同一レベルで索引をパーティション化することにデメリットはありませんが、問合せ計画を生成したりパーティションのメンテナンス操作を実行したりする際に、Oracleが同一レベル・パーティション化のメリットを利用することもありません。したがって、基礎となる表と同一レベルでパーティション化する索引は、LOCAL
として作成する必要があります。
グローバル・パーティション索引には、すべてのパーティションのすべての行に対するエントリを持つBツリーが1つ含まれます。各索引パーティションは、表の中の様々なパーティションまたはサブパーティションを参照するキーを含むことができます。
グローバル索引の最上位パーティションのパーティション・バウンドは、含まれるすべての値がMAXVALUE
であることが必要です。これにより、基礎となる表のすべての行を、確実に索引の中で表すことができるようになります。
次の内容について説明します。
3.3.2.1 同一キーおよび非同一キーのグローバル・パーティション索引
索引列の左プリフィックスでパーティション化されているグローバル・パーティション索引は、同一キー索引です。
索引列の左プリフィックスでパーティション化されていないグローバル・パーティション索引は、非同一キー索引です。Oracleでは、グローバル非同一キー・パーティション索引はサポートされていません。例は図3-6を参照してください。
グローバル同一キー・パーティション索引は、一意にも非一意にもできます。非パーティション索引は、グローバル同一キー非パーティション索引として扱われます。
3.3.2.2 グローバル・パーティション索引の管理
グローバル・パーティション索引の管理には、いくつかの課題があります。
次の理由から、グローバル・パーティション索引は、ローカル索引よりも管理が煩雑です。
-
基礎となる表のパーティションのデータが移動または削除された場合(
SPLIT
、MOVE
、DROP
またはTRUNCATE
)、グローバル索引のすべてのパーティションが影響を受けます。つまり、グローバル索引では、パーティションの独立性がサポートされていません。 -
基礎となる表のパーティションまたはサブパーティションをある時点までリカバリする場合は、グローバル索引の対応するすべてのエントリを同じ時点までリカバリする必要があります。これらのエントリは、索引のすべてのパーティションまたはサブパーティションに点在していたり、リカバリしない他のパーティションまたはサブパーティションのエントリと混在していたりする可能性があるので、この処理を行うには、グローバル索引全体を再作成する以外に方法はありません。
3.3.3 パーティション索引のまとめ
このトピックでは、パーティション索引タイプの概要を示します。
表3-1に、Oracleでサポートされている各タイプのパーティション索引をまとめます。重要な点は次のとおりです。
-
索引がローカルの場合は、基礎となる表と同一レベルでパーティション化されます。これ以外の索引はグローバルです。
-
同一キー索引は、索引列の左プリフィックスでパーティション化されます。これ以外の索引は非同一キーです。
表3-1 パーティション索引のタイプ
索引のタイプ | 表と同一レベルでパーティション化された索引 | 索引列の左プリフィックスでパーティション化された索引 | UNIQUE属性の可/不可 | 例: 表のパーティション化キー | 例: 索引列 | 例: 索引のパーティション化キー |
---|---|---|---|---|---|---|
ローカル同一キー(任意のパーティション化方法) |
可 |
可 |
可 |
A |
A、B |
A |
ローカル非同一キー(任意のパーティション化方法) |
可 |
不可 |
可脚注 1 |
A |
B、A |
A |
グローバル同一キー(レンジ・パーティション化のみ) |
不可脚注 2 |
可 |
可 |
A |
B |
B |
脚注1
一意ローカル非同一キー索引の場合、パーティション化キーは索引キーのサブセットにする必要があり、部分索引にできません。
脚注2
グローバル・パーティション索引は基礎となる表と同一レベルでパーティション化することもできますが、Oracleが同一レベル・パーティション化のメリットを利用したり、パーティションのメンテナンス操作(DROPまたはSPLIT PARTITION)の後に同一レベル・パーティション化をメンテナンスしたりすることはありません。
3.3.4 非同一キー索引の重要性
非同一キー索引は、履歴データベースで特に役立つため重要です。
履歴データを含む表では、索引を1つの列に定義して、その列への高速アクセスの要件を満たすことが一般的です。ただし、古いデータの削除と新しいデータの取得の期間を合せるために、索引を別の列(基礎となる表と同じ列)でパーティション化することもできます。
sales
表が週単位でパーティション化されているとします。1年分のデータが含まれ、13個のパーティションに分かれます。week_no
でレンジ・パーティション化されており、4週が1パーティションになります。非同一キー・ローカル索引sales_ix
をsales
に作成します。問合せでは口座番号を使用してデータに高速アクセスする必要があるため、sales_ix
索引はacct_no
に定義されます。ただし、これはsales
表に合せてweek_no
でパーティション化されています。4週ごとにsales
とsales_ix
の一番古いパーティションが削除され、新しいパーティションが追加されます。
3.3.5 同一キー索引および非同一キー索引がパフォーマンスに与える影響
同一キー索引および非同一キー索引がパフォーマンスに与える影響があります。
同一キー索引を使用すると、パーティション・プルーニングの取得の見込みが、非同一キー索引を使用する場合と比べて大幅に高くなります。列が索引の一部である場合、この列はフィルタ述語として使用されると想定でき、これは、フィルタされた列が同一キー索引列の場合に、ある程度のプルーニングであることを自動的に意味します。この結果は、同一キー索引のプローブは、非同一キー索引のプローブよりも低コストであることを意味します。索引が同一キー索引のときに(ローカルまたはグローバルのいずれでも)、索引列を含む条件がOracleに発行されると、パーティション・プルーニングによって、条件の適用範囲を索引パーティションのサブセットに限定できます。
たとえば、図3-4において、条件がdeptno=15
である場合、オプティマイザはこの条件を索引の2番目のパーティションにのみ適用すればよいことを認識します。(条件にバインド変数が含まれている場合、オプティマイザは条件を適用するべきパーティションを正確には認識できませんが、関係があるパーティションは1つのみであることはわかっており、実行時には1つの索引パーティションにのみアクセスします。)
索引が非同一キー索引である場合、Oracleは通常、索引列を含む条件をN
個の索引パーティションすべてに適用する必要があります。このためには、単一のキーを参照するか、または索引レンジ・スキャンを実行する必要があります。レンジ・スキャンの場合、Oracleは、N
個の索引パーティションの情報を結合する必要もあります。たとえば、図3-5で、ローカル索引はchkdate
でパーティション化されており、索引キーはacctno
にあります。条件がacctno=31
である場合、Oracleは12個の索引パーティションすべてをプローブします。
パーティション列に対する条件もある場合は、索引のプローブを複数実行する必要はありません。Oracleは、ローカル索引は基礎となる表と同一レベルでパーティション化されるという特性を利用し、パーティション・キーに基づいてパーティションをプルーニングします。たとえば、図3-5において条件がchkdate<3/97
である場合、Oracleがプローブする必要のあるパーティションは2つのみです。
このように、非同一キー索引では、パーティション・キーがWHERE
句に含まれるが索引キーの一部ではない場合には、オプティマイザが、基礎となる表のパーティションに基づいてプローブするべき索引パーティションを判断します。
ローカルの非同一キー索引のキーを使用する大量の問合せおよびDML文がすべての索引パーティションをプローブする必要がある場合は、この仕組みによって、ローカル非同一キー索引がもたらすパーティションの独立性の程度が実質的に低くなります。
表3-2 同一キー・ローカル索引、非同一キー・ローカル索引およびグローバル索引の比較
索引の特性 | 同一キー・ローカル | 非同一キー・ローカル | グローバル |
---|---|---|---|
一意索引の可/不可 |
可 |
可 |
可。パーティション列以外の列の索引を使用する場合はグローバルである必要がある。 |
管理のしやすさ |
容易 |
容易 |
煩雑 |
OLTP |
適切 |
不適切 |
適切 |
長時間実行(DSS) |
適切 |
適切 |
適切でない |
3.3.6 パーティション索引での拡張索引圧縮
パーティション索引での拡張索引圧縮により、索引の記憶域要件を低減できます。
拡張索引圧縮を使用して索引を作成することで、サポートされているすべての一意索引と非一意索引のサイズが低減します。拡張索引圧縮は、索引への効率的なアクセスを提供しつつ、圧縮率を著しく向上させます。拡張圧縮は、接頭辞圧縮の候補として適切ではない索引を含め、サポートされているすべての索引で適切に機能します。
パーティション索引の場合は、パーティションごとにパーティションの圧縮タイプを指定できます。親索引が圧縮されていない場合でも、索引パーティションに対して拡張索引圧縮を指定できます。
次の例は、パーティション索引での圧縮属性の混在を示しています。
CREATE INDEX my_test_idx ON test(a, b) COMPRESS ADVANCED HIGH LOCAL (PARTITION p1 COMPRESS ADVANCED LOW, PARTITION p2 COMPRESS, PARTITION p3, PARTITION p4 NOCOMPRESS);
次の例では、親索引が圧縮されていないパーティションでの拡張索引圧縮のサポートを示します。
CREATE INDEX my_test_idx ON test(a, b) NOCOMPRESS LOCAL (PARTITION p1 COMPRESS ADVANCED LOW, PARTITION p2 COMPRESS ADVANCED HIGH, PARTITION p3);
関連項目:
拡張索引圧縮の詳細は、『Oracle Database管理者ガイド』を参照してください
3.3.7 索引のパーティション化のガイドライン
索引のパーティション化に関しては、いくつかのガイドラインがあります。
表の索引のパーティション化方法を決める際は、表にアクセスする必要があるアプリケーションの組合せを考慮します。どの方法を使用するかは、パフォーマンスと、可用性および管理性とのトレードオフになります。この項では、考慮する必要のあるいくつかのガイドラインを示します。
-
OLTPアプリケーションの場合:
-
グローバル索引およびローカル同一キー索引では、索引パーティションのプローブ数が最小限になるので、ローカル非同一キー索引よりもパフォーマンスが向上します。
-
ローカル索引では、表のパーティションまたはサブパーティションのメンテナンス操作中でも、より高い可用性が得られます。ローカル非同一キー索引は、履歴データベースで特に有効です。
-
-
DSSアプリケーションでは、ローカル非同一キー索引によってパフォーマンスを向上させることができます。これは、索引キーに基づくレンジ問合せによって、多数の索引パーティションをパラレルにスキャンできるためです。
たとえば、図3-5の
checks
表に対してacctno
between 40 and 45という述語を使用する問合せでは、非同一キー索引ix3
のすべてのパーティションのパラレル・スキャンが実行されます。また、図3-4のdeptno
表に対してdeptno BETWEEN 40 AND 45
という述語を使用する問合せは、同一キー索引ix1
の1つのパーティションにアクセスするため、パラレル化できません。 -
履歴表では、索引はできるかぎりローカルにする必要があります。これにより、定期的なパーティション削除操作の影響を抑えることができます。
-
パーティション列以外の列の一意索引はグローバルにする必要があります。これは、キーにパーティション化キーが含まれていない一意ローカル非同一キー索引はサポートされていないためです。
-
使用できない索引は領域を消費しません。
関連項目:
表の管理のガイドラインの詳細は、『Oracle Database管理者ガイド』を参照してください
3.3.8 索引パーティションの物理属性
このトピックでは、索引パーティションの物理属性について説明します。
デフォルトの物理属性は、CREATE
INDEX
文でパーティション索引を作成する際に初期指定されます。パーティション索引自体に対応するセグメントはないので、これらの属性はメンバー・パーティションの物理属性を導出する際にのみ使用されます。デフォルトの物理属性は、ALTER
INDEX
MODIFY
DEFAULT
ATTRIBUTES
を使用して後から変更できます。
CREATE
INDEX
で作成されるパーティションの物理属性は、次のようにして決定されます。
-
索引に指定される(明示的またはデフォルト)物理属性の値が使用されるのは、対応するパーティション属性の値が指定されない場合です。
LOCAL
索引のパーティションのTABLESPACE
属性の扱いは、このルールの重要な例外です。つまり、ユーザー指定のTABLESPACE
値(パーティション・レベルと索引レベルの両方)がない場合、基礎となる表の対応するパーティションの物理属性の値が使用されます。 -
ALTER
TABLE
ADD
PARTITION
の処理中に作成されるローカル索引のパーティションの物理属性(前項で説明したTABLESPACE
以外)は、各索引のデフォルトの物理属性に設定されます。
ALTER
TABLE
SPLIT
PARTITION
で作成される索引パーティションの物理属性(TABLESPACE
以外)は、次のようにして決定されます。
-
分割される索引パーティションの物理属性の値が使用されます。
既存の索引パーティションの物理属性は、ALTER
INDEX MODIFY
PARTITION
およびALTER
INDEX
REBUILD
PARTITION
で変更できます。その結果の属性は、次のようにして決定されます。
-
新しい値が指定されていない場合は、文が発行される前のパーティションの物理属性の値が使用されます。
ALTER
INDEX
REBUILD PARTITION
SQL文で、パーティションが含まれる表領域を変更できます。
ALTER
INDEX
SPLIT PARTITION
で作成されるグローバル索引パーティションの物理属性は、次のようにして決定されます。
-
新しい値が指定されていない場合は、分割されるパーティションの物理属性の値が使用されます。
-
索引のすべてのパーティションの(デフォルト値を持つ)物理属性は、
ALTER
INDEX
で変更できます。たとえば、ALTER
INDEX
indexname
NOLOGGING
は、indexname
のすべてのパーティションのロギング・モードをNOLOGGING
に変更します。
関連項目:
パーティションの追加や索引の再作成の詳しい例は、「パーティションの管理」を参照してください