グローバルインデックス作成は、パーティションテーブルのインデックス作成手法です。 非パーティションキーを使用して、パーティションテーブルにグローバルインデックスを作成できます。 グローバルインデックスは、一意の制約を提供できます。
構文
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ]
( { column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
[ INCLUDE ( column_name [, ...] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ GLOBAL/LOCAL ]
[ TABLESPACE tablespace_name ]
[ WHERE predicate ]
説明
グローバルインデックスを作成するには、create indexステートメントで
LOCAL
キーワードの代わりにglobal
キーワードを指定する必要があります。GLOBALまたはLOCALキーワードを指定しない場合、デフォルトでローカルインデックスが作成されます。
CONCURRENTLYは、グローバルインデックスを作成するCREATE INDEXステートメントで指定できます。
非パーティションテーブルまたはパーティションテーブルの子テーブルのグローバルインデックスは作成できません。
式に基づいてグローバルインデックスを作成することはできません。
パーティションテーブルのパーティションキー列に基づいてグローバルインデックスを作成することはできません。
グローバルインデックスには、次の利点があります。
グローバルインデックスは、パーティションテーブルの非パーティションキー列に一意の制約を提供できます。
グローバルインデックスは、非パーティションキー列を使用してパーティション分割テーブルに対して作成されます。 これにより、グローバルインデックスは、パーティションキーが指定されていないシナリオでパーティションテーブルに対するクエリを高速化できます。
ノード間の並列実行機能を使用すると、Bツリーインデックスのグローバルインデックスの作成プロセスを高速化できます。 詳細については、「インデックス作成の高速化」をご参照ください。
例
以下の例では、テーブルは時間によって分割されます。 パーティションは、以前のパーティションを置き換えるために定期的に作成されます。
CREATE TABLE partition_range (
id integer,
a int,
b int,
created_date timestamp without time zone
)
PARTITION BY RANGE (created_date);
CREATE TABLE partition_range_part01 (
id integer,
a int,
b int,
created_date timestamp without time zone
);
ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part01 FOR VALUES FROM (MINVALUE) TO ('2020-01-01 00:00:00');
CREATE TABLE partition_range_part02 (
id integer,
a int,
b int,
created_date timestamp without time zone
);
ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part02 FOR VALUES FROM ('2020-01-01 00:00:00') TO ('2020-02-01 00:00:00');
CREATE TABLE partition_range_part03 (
id integer,
a int,
b int,
created_date timestamp without time zone
);
ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part03 FOR VALUES FROM ('2020-02-01 00:00:00') TO ('2020-03-01 00:00:00');
CREATE TABLE partition_range_part04 (
id integer,
a int,
b int,
created_date timestamp without time zone
);
ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part04 FOR VALUES FROM ('2020-03-01 00:00:00') TO ('2020-04-01 00:00:00');
CREATE TABLE partition_range_part05 (
id integer,
a int,
b int,
created_date timestamp without time zone
);
ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part05 FOR VALUES FROM ('2020-04-01 00:00:00') TO ('2020-05-01 00:00:00');
多数のパーティションテーブルが存在する場合、created_date
パーティションキーがクエリで指定されていないと、クエリのパフォーマンスが低下します。
EXPLAIN (costs off) SELECT * FROM partition_range WHERE ID = 6;
次の応答が返されます。
QUERY PLAN
------------------------------------------
Append
-> Seq Scan on partition_range_part01
Filter: (id = 6)
-> Seq Scan on partition_range_part02
Filter: (id = 6)
-> Seq Scan on partition_range_part03
Filter: (id = 6)
(7 rows)
この問題を解決するには、グローバルインデックスを作成してクエリのパフォーマンスを向上させます。 次のステートメントを実行して、グローバルインデックスを作成します。
CREATE UNIQUE INDEX idx_partition_range_global ON partition_range(id) global;
グローバルインデックスを作成すると、次の例に示すように、クエリのパフォーマンスが向上します。
EXPLAIN (costs off) SELECT * FROM partition_range WHERE ID = 6;
次の応答が返されます。
QUERY PLAN
-----------------------------------------------------------------------
Global Index Scan using idx_partition_range_global on partition_range
Index Cond: (id = 6)
(2 rows)
グローバルインデックスが作成されているパーティションテーブルにパーティションをアタッチまたはデタッチできます。
新しいパーティションをアタッチします。
CREATE TABLE partition_range_part06 ( id integer, a int, b int, created_date timestamp without time zone ); ALTER TABLE ONLY partition_range ATTACH PARTITION partition_range_part06 FOR VALUES FROM ('2020-05-01 00:00:00') TO ('2020-06-01 00:00:00');
前のパーティションをデタッチします。
ALTER TABLE partition_range DETACH PARTITION partition_range_part01;