All Products
Search
Document Center

PolarDB:Create a global index

Last Updated:Sep 13, 2024

Global indexing is an indexing technique for partitioned tables. You can create global indexes on partitioned tables by using non-partition keys. Global indexes can provide unique constraints.

Syntax

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 ]

Description

  • To create a global index, you must specify the GLOBAL keyword instead of the LOCAL keyword in the CREATE INDEX statement.

  • If you do not specify the GLOBAL or LOCAL keyword, a local index is created by default.

  • You can specify CONCURRENTLY in a CREATE INDEX statement that creates a global index.

  • You cannot create global indexes for non-partitioned tables or the child tables of partitioned tables.

  • You cannot create global indexes based on expressions.

  • You cannot create global indexes based on the partition key columns of partitioned tables.

Global indexes provide the following benefits:

  • Global indexes can provide unique constraints on the non-partition key columns of partitioned tables.

  • Global indexes are created for partitioned tables by using non-partition key columns. This allows global indexes to accelerate queries on partitioned tables in scenarios in which no partition keys are specified.

  • You can use the cross-node parallel execution feature to accelerate the process of creating global indexes of B-tree indexes. For more information, see Accelerate index creation.

Examples

In the following examples, a table is partitioned by time. Partitions are created on a regular basis to replace previous partitions.

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');

When a large number of partitioned tables exist, if the created_date partition key is not specified in queries, the query performance is reduced.

EXPLAIN (costs off) SELECT * FROM partition_range WHERE ID = 6;

The following result is returned:

                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)

To resolve this issue, you can create global indexes to improve query performance. Execute the following statement to create a global index:

CREATE UNIQUE INDEX idx_partition_range_global ON partition_range(id) global;

After the global index is created, the query performance is improved, as shown in the following example:

EXPLAIN (costs off) SELECT * FROM partition_range WHERE ID = 6;

The following result is returned:

                              QUERY PLAN                               
-----------------------------------------------------------------------
 Global Index Scan using idx_partition_range_global on partition_range
   Index Cond: (id = 6)
(2 rows)

You can attach partitions to or detach partitions from partitioned tables for which global indexes are created.

  • Attach a new partition.

    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');
  • Detach a previous partition.

    ALTER TABLE partition_range DETACH PARTITION partition_range_part01;