Meningkatkan performa INSERT SELECT dengan SELECT paralel

Menggunakan eksekusi paralel untuk bagian SELECT dari kueri INSERT INTO ... SELECT dapat meningkatkan performa kueri AlloyDB untuk PostgreSQL, terutama untuk tabel yang dipartisi dan kueri yang kompleks.

Dengan memparalelkan subrencana SELECT, database menggunakan beberapa proses worker untuk mengambil data. Kemudian, database akan menyisipkan data yang diambil ke dalam tabel target. Pembagian tugas ini dapat meningkatkan performa database.

Cara kerja paket kueri paralel di PostgreSQL

Di PostgreSQL, pengoptimal kueri dapat membuat rencana paralel untuk seluruh kueri atau sebagian kueri. Saat rencana paralel dibuat, rencana tersebut akan menambahkan node Gather atau Gather Merge di bagian atas rencana.

Node ini mengoordinasikan beberapa proses pekerja paralel. Setiap pekerja menjalankan sebagian tugas, misalnya, memindai sebagian tabel. Node Gather kemudian mengumpulkan hasil dari semua pekerja dan meneruskannya ke tahap kueri berikutnya, atau kembali ke klien.

Misalnya, rencana kueri berikut menunjukkan node Gather yang berencana menggunakan lima proses pekerja untuk pemindaian berurutan paralel pada tabel t1.

EXPLAIN SELECT * FROM t1;

                  QUERY PLAN
-------------------------------------------------------------
 Gather  (cost=0.00..143359.76 rows=9999878 width=60)
   Workers Planned: 5
   ->  Parallel Seq Scan on t1  (cost=0.00..143359.76 rows=1999976 width=60)
(3 rows)

Eksekusi paralel untuk pernyataan INSERT...SELECT

AlloyDB meningkatkan performa INSERT INTO ... SELECT dengan menggunakan beberapa proses pekerja untuk memparalelkan pernyataan SELECT. Pembagian tugas ini dapat meningkatkan performa database. Kueri harus aman untuk paralel dan tidak boleh ada kondisi yang mencegah paralelisasi.

Banyak operasi database menggunakan pernyataan INSERT INTO ... SELECT untuk menambahkan baris baru ke tabel. Sering kali, bagian SELECT dari pernyataan adalah bagian kueri yang paling banyak menggunakan resource.

Fungsi ini dikontrol oleh parameter konfigurasi berikut:

  • enable_parallel_select_for_insert_select: mengaktifkan atau menonaktifkan fitur . Parameter ini aktif secara default di PostgreSQL 14 dan yang lebih baru.
  • enable_parallel_select_for_insert_select_into_part_table: mengaktifkan atau menonaktifkan fitur yang memungkinkan Anda menyisipkan data ke dalam tabel berpartisi. Parameter ini dinonaktifkan secara default di PostgreSQL 16 dan yang lebih baru.

Agar perencana kueri mempertimbangkan rencana paralel, pernyataan INSERT SELECT harus aman untuk paralel. Artinya, tidak ada bagian operasi yang boleh berisi fungsi atau ekspresi yang tidak dapat dieksekusi secara paralel dengan aman. Jika ada bagian kueri yang dianggap tidak aman untuk paralel, pengoptimal akan kembali ke rencana non-paralel. Untuk mengetahui informasi selengkapnya, lihat parallel-safety.

Kondisi yang mencegah eksekusi paralel

Pengoptimal kueri tidak menggunakan rencana paralel jika pernyataan INSERT SELECT dianggap tidak aman untuk paralel. Kondisi berikut mencegah paralelisasi:

  • Tabel target adalah tabel asing.
  • Kueri menggunakan Ekspresi Tabel Umum (CTE) yang dapat diubah yang berisi pernyataan modifikasi data, misalnya, DELETE.
  • Indeks pada tabel target menggunakan ekspresi atau fungsi yang tidak aman secara paralel.
  • Kolom pada tabel target memiliki nilai default yang menggunakan fungsi tidak aman paralel.
  • Pemicu pada tabel target menggunakan ekspresi atau fungsi yang tidak aman secara paralel.
  • Tabel target memiliki kolom DOMAIN dengan batasan CHECK yang menggunakan fungsi tidak aman paralel.
  • Batasan CHECK pada tabel target berisi ekspresi atau fungsi yang tidak aman untuk paralel.
  • Tabel target adalah tabel berpartisi dan enable_parallel_select_for_insert_select_into_part_table dinonaktifkan.

Sebelum memulai

Dokumen ini mengasumsikan bahwa Anda memiliki database AlloyDB. Untuk membuat database, lihat Membuat cluster dan instance utamanya serta Membuat dan mengelola database.

Peran yang diperlukan

Untuk mendapatkan izin yang diperlukan guna mengubah flag database di tingkat sesi, minta administrator untuk memberi Anda peran Identity and Access Management (IAM) AlloyDB Database User (roles/alloydb.databaseUser) di project Anda. Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

Mengaktifkan parameter eksekusi paralel

Untuk mengaktifkan eksekusi paralel untuk tabel target berpartisi, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud , buka halaman Clusters.

    Buka Cluster

  2. Pilih cluster dari daftar.

  3. Di menu navigasi, klik AlloyDB Studio.

  4. Login ke AlloyDB Studio menggunakan nama database, nama pengguna, dan sandi Anda.

  5. Tetapkan GUC enable_parallel_select_for_insert_select_into_part_table ke on.

    SET enable_parallel_select_for_insert_select_into_part_table = on;
    

    Setelah Anda mengaktifkan parameter GUC, perencana kueri akan otomatis mempertimbangkan rencana paralel untuk pernyataan INSERT INTO ... SELECT yang tujuannya adalah tabel yang dipartisi, asalkan kueri ditentukan sebagai aman untuk paralel.

    Contoh berikut menghasilkan rencana EXPLAIN yang menampilkan node Gather, yang menunjukkan bahwa SELECT dari source_table dieksekusi secara paralel.

    -- Create a partitioned table
    CREATE TABLE part_table (a INT, b TEXT) PARTITION BY RANGE (a);
    CREATE TABLE part_table_1 PARTITION OF part_table FOR VALUES FROM (MINVALUE) TO (1000);
    CREATE TABLE part_table_2 PARTITION OF part_table FOR VALUES FROM (1000) TO (MAXVALUE);
    
    -- Create a source table
    CREATE TABLE source_table (c1 INT, c2 TEXT);
    INSERT INTO source_table SELECT i, 'value_' || i FROM generate_series(1, 2000) i;
    ANALYZE source_table;
    
    -- Enable the feature
    SET enable_parallel_select_for_insert_select_into_part_table = on;
    -- Optional for parallelizing the query with a small amount of data
    SET parallel_setup_cost=0;
    SET parallel_tuple_cost=0;
    SET min_parallel_table_scan_size=0;
    
    -- Run the insert with a parallelizable select
    EXPLAIN INSERT INTO part_table SELECT * FROM source_table;
    

    Tindakan ini akan menampilkan output berikut:

    EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table;
                    QUERY PLAN                   
    -----------------------------------------------
    Insert on part_table
    ->  Gather
            Workers Planned: 2
            ->  Parallel Seq Scan on source_table
    (4 rows)
    

Menonaktifkan parameter eksekusi paralel

Untuk menonaktifkan parameter, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud , buka halaman Clusters.

    Buka Cluster

  2. Pilih cluster dari daftar.

  3. Di menu navigasi, klik AlloyDB Studio.

  4. Login ke AlloyDB Studio menggunakan nama database, nama pengguna, dan sandi Anda.

  5. Untuk menonaktifkan parameter enable_parallel_select_for_insert_select, jalankan perintah SQL berikut:

    SET enable_parallel_select_for_insert_select = OFF;
    
  6. Untuk menonaktifkan parameter enable_parallel_select_for_insert_select_into_part_table, jalankan perintah SQL berikut:

    SET enable_parallel_select_for_insert_select_into_part_table = OFF;
    

Memverifikasi rencana paralel

Anda dapat memverifikasi bahwa pengoptimal menggunakan rencana paralel dengan menggunakan perintah EXPLAIN. Cari node Gather dan atribut Workers Planned atau Workers Launched dalam rencana kueri.

Contoh tabel standar

Dalam contoh rencana berikut, enam proses pekerja diluncurkan untuk gabungan hash paralel guna menjalankan pernyataan SELECT.

EXPLAIN (ANALYZE)
INSERT INTO t1 SELECT t2.* FROM t1, t2 WHERE t1.c1 != t2.c1 AND t1.c2 = t2.c2;

                                 QUERY PLAN
------------------------------------------------------------------------------------
 Insert on t1  (cost=1209138.00..12801765.49 rows=0 width=0) (actual time=16812.677..19337.150 rows=0 loops=1)
   ->  Gather  (cost=1209138.00..12801765.49 rows=99995407 width=24) (actual time=16812.674..19337.144 rows=0 loops=1)
         Workers Planned: 6
         Workers Launched: 6
         ->  Parallel Hash Join  (...)
(...)

Contoh tabel berpartisi

Contoh berikut menunjukkan bahwa, setelah Anda mengaktifkan fitur untuk tabel berpartisi, rencana menampilkan node Gather dengan empat pekerja yang direncanakan untuk SELECT.

-- First, enable the feature for partitioned tables
SET enable_parallel_select_for_insert_select_into_part_table = ON;

-- Then, explain the query
EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table;
                  QUERY PLAN                   
-----------------------------------------------
 Insert on part_table
   ->  Gather
         Workers Planned: 2
         ->  Parallel Seq Scan on source_table
(4 rows)

Langkah berikutnya