すべてのプロダクト
Search
ドキュメントセンター

PolarDB:グローバルインデックスの作成

最終更新日:Sep 26, 2024

グローバルインデックス作成は、パーティションテーブルのインデックス作成手法です。 非パーティションキーを使用して、パーティションテーブルにグローバルインデックスを作成できます。 グローバルインデックスは、一意の制約を提供できます。

構文

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;