All Products
Search
Document Center

PolarDB:Indeks Global

Last Updated:Dec 27, 2025

Indeks global adalah indeks yang dibuat pada kolom non-kunci partisi dari tabel partisi dan dapat menerapkan kendala UNIK.

Applicability

Fitur ini didukung pada kluster PolarDB for PostgreSQL yang menjalankan PostgreSQL 14 dengan versi mesin minor 2.0.14.9.15.0 atau lebih baru.

Catatan

Anda dapat melihat nomor versi mesin minor di console atau dengan menjalankan pernyataan SHOW polardb_version;. Jika versi mesin minor tidak memenuhi persyaratan, Anda dapat upgrade the minor engine version.

Informasi Latar Belakang

Seiring pertumbuhan data bisnis, partisi data menjadi fitur utama dalam database tingkat enterprise dan metode penting untuk mengurangi skala data. Tabel partisi dibagi menjadi beberapa tabel anak independen berdasarkan kunci partisi. Tabel-tabel anak tersebut dikelola secara terpisah guna meningkatkan kemudahan pengelolaan, kinerja keseluruhan, serta penyeimbangan beban.

Banyak pengguna PolarDB for PostgreSQL dan menggunakan tabel partisi untuk mengelola data mereka. Kasus penggunaan umum adalah mempartisi data berdasarkan waktu:

  • Gunakan waktu sebagai kunci partisi untuk tabel partisi.

  • Buat subpartisi baru secara berkala—misalnya mingguan atau bulanan—untuk menyimpan data baru.

  • Arsipkan subpartisi lama secara rutin untuk mengurangi biaya operasi dan maintenance (O&M) tabel partisi.

Dalam skenario tersebut, waktu biasanya digunakan sebagai kunci partisi, bukan sebagai primary key atau ID unik. Hal ini menimbulkan dua masalah:

  • Saat melakukan kueri data menggunakan kunci non-partisi, semua subpartisi harus dipindai karena sistem tidak dapat menentukan partisi mana yang berisi data tersebut.

  • Saat memodifikasi data menggunakan kunci non-partisi, keunikan data tidak dapat dijamin di seluruh tabel partisi.

Untuk mengatasi masalah ini, PolarDB for PostgreSQL dan menyediakan fitur indeks global. Berbeda dengan indeks lokal yang secara default dibuat pada setiap subpartisi, satu indeks global mencakup seluruh data tabel partisi—artinya satu indeks bersesuaian dengan beberapa subpartisi. Hal ini memungkinkan penerapan kendala unik secara global serta peningkatan signifikan pada kinerja kueri berdasarkan kunci non-partisi.

Batasan

  • Anda tetap dapat ATTACH atau DETACH subpartisi dari tabel partisi yang memiliki indeks global.

  • Tentukan kata kunci GLOBAL dalam pernyataan `CREATE INDEX` untuk membuat indeks global. Jika kata kunci ini tidak ditentukan, indeks lokal akan dibuat secara default.

  • Anda dapat membuat indeks global secara konkuren dengan menentukan kata kunci CONCURRENTLY.

  • Anda tidak dapat membuat indeks global pada tabel non-partisi atau pada tabel anak yang berisi subpartisi.

  • Indeks global tidak mendukung indeks ekspresi.

  • Anda tidak dapat membuat indeks global pada kolom kunci partisi dari tabel partisi.

Sintaks

Anda dapat membuat indeks global.

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 ]

    Contoh

    Percepat query kunci non-partisi

    1. Buat tabel partisi dengan kolom waktu sebagai kunci partisi.

      CREATE TABLE partition_range (
          id INT,
          a INT,
          b INT,
          created_date TIMESTAMP WITHOUT TIME ZONE
      ) PARTITION BY RANGE (created_date);
      
      CREATE TABLE partition_range_part01 PARTITION OF partition_range FOR VALUES FROM (MINVALUE) TO ('2020-01-01 00:00:00');
      CREATE TABLE partition_range_part02 PARTITION OF partition_range FOR VALUES FROM ('2020-01-01 00:00:00') TO ('2020-02-01 00:00:00');
      CREATE TABLE partition_range_part03 PARTITION OF partition_range FOR VALUES FROM ('2020-02-01 00:00:00') TO ('2020-03-01 00:00:00');
    2. Lakukan kueri pada tabel partisi berdasarkan kondisi kunci non-partisi.

      EXPLAIN (COSTS OFF) SELECT * FROM partition_range WHERE id = 1;

      Hasilnya menunjukkan bahwa semua subpartisi dipindai. Fitur pemangkasan partisi tidak dapat digunakan.

                              QUERY PLAN
      ------------------------------------------------------------
       Append
         ->  Seq Scan on partition_range_part01 partition_range_1
               Filter: (id = 1)
         ->  Seq Scan on partition_range_part02 partition_range_2
               Filter: (id = 1)
         ->  Seq Scan on partition_range_part03 partition_range_3
               Filter: (id = 1)
      (7 rows)
    3. Buat indeks lokal pada tabel partisi, lalu jalankan kueri lagi.

      CREATE INDEX partition_range_idx_local ON partition_range(id);
      
      EXPLAIN (COSTS OFF) SELECT * FROM partition_range WHERE id = 1;

      Hasilnya menunjukkan bahwa indeks lokal dari semua subpartisi tetap dipindai karena indeks lokal dibuat pada setiap subpartisi.

                                                  QUERY PLAN
      --------------------------------------------------------------------------------------------------
       Append
         ->  Index Scan using partition_range_part01_id_idx on partition_range_part01 partition_range_1
               Index Cond: (id = 1)
         ->  Index Scan using partition_range_part02_id_idx on partition_range_part02 partition_range_2
               Index Cond: (id = 1)
         ->  Index Scan using partition_range_part03_id_idx on partition_range_part03 partition_range_3
               Index Cond: (id = 1)
      (7 rows)

    4. Gunakan kata kunci GLOBAL untuk membuat indeks global pada tabel partisi, lalu jalankan kueri lagi.

      CREATE INDEX partition_range_idx_global ON partition_range(id) GLOBAL;
      
      EXPLAIN (COSTS OFF) SELECT * FROM partition_range WHERE id = 1;

      Hasilnya menunjukkan bahwa database menggunakan indeks global untuk langsung menemukan subpartisi yang berisi data tersebut.

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

    Kendala unik untuk kunci non-partisi

    Gunakan tabel partisi yang sama seperti pada contoh sebelumnya. Kunci partisinya adalah created_date, sedangkan kolom yang memerlukan kendala unik adalah id.

    CREATE UNIQUE INDEX partition_range_id_unique_idx ON partition_range(id);
    ERROR:  unique constraint on partitioned table must include all partitioning columns
    DETAIL:  UNIQUE constraint on table "partition_range" lacks column "created_date" which is part of the partition key.
    Catatan

    Pada PostgreSQL native, upaya membuat kendala UNIK pada kunci non-partisi menggunakan indeks lokal akan menghasilkan error. Pesan error tersebut menunjukkan bahwa kunci partisi harus disertakan dalam indeks. PolarDB for PostgreSQL dan telah meningkatkan fitur indeks global. Secara default, kendala UNIK pada kunci non-partisi dikonversi menjadi kendala global berbasis indeks global. Perilaku ini dikontrol oleh parameter polar_pk_in_non_partition_column_mode dengan nilai default global_index. Jika nilai parameter diubah menjadi none, perilakunya akan sama seperti PostgreSQL native.

    Namun, pembatasan ini tidak berlaku saat Anda menambahkan kendala UNIK ke indeks global, seperti yang ditunjukkan di bawah ini.

    CREATE UNIQUE INDEX partition_range_id_unique_idx ON partition_range(id) GLOBAL;

    Uji Performa

    Anda dapat menggunakan pgbench untuk menghasilkan data dengan faktor skala 80000 serta membuat tabel partisi dan tabel non-partisi.

    Performa kueri titik pada kunci non-partisi

    Kategori

    TPS

    Pernyataan Siap

    Tidak digunakan

    Digunakan

    Konkurensi

    1

    32

    64

    1

    32

    64

    Standard table

    27.732

    494.433

    430.848

    53.935

    985.880

    886.882

    Partitioned table + local index

    367

    4.155

    3.688

    856

    8.742

    6.790

    Partitioned table + global index

    19.006

    308.128

    262.941

    45.090

    820.924

    731.557

    Performa TPC-B pada kunci non-partisi

    Catatan

    Ini mencakup kueri titik dan pernyataan Data Manipulation Language (DML).

    Kategori

    TPS

    Pernyataan Siap

    Tidak digunakan

    Digunakan

    Konkurensi

    1

    32

    64

    1

    32

    64

    Standard table

    1.115

    51.025

    60.409

    4.822

    90.312

    100.802

    Partitioned table + local index

    271

    2.903

    2.524

    550

    5.276

    4.237

    Partitioned table + global index

    Tidak didukung

    4.334

    69.040

    75.232

    Kesimpulan

    Indeks global dapat meningkatkan kinerja kueri titik dan pernyataan DML pada tabel partisi hingga satu orde besar.