PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Panduan Mempartisi Data Di PostgreSQL

Apa itu Partisi Data?

Untuk database dengan tabel yang sangat besar, mempartisi adalah trik yang luar biasa dan licik bagi perancang database untuk meningkatkan kinerja database dan membuat perawatan menjadi lebih mudah. Ukuran tabel maksimum yang diizinkan dalam database PostgreSQL adalah 32 TB, namun kecuali jika dijalankan pada komputer yang belum ditemukan di masa mendatang, masalah kinerja mungkin muncul pada tabel dengan hanya seperseratus ruang tersebut.

Partisi membagi tabel menjadi beberapa tabel, dan umumnya dilakukan sedemikian rupa sehingga aplikasi yang mengakses tabel tidak melihat perbedaan apa pun, selain lebih cepat untuk mengakses data yang dibutuhkannya. Dengan membagi tabel menjadi beberapa tabel, idenya adalah untuk memungkinkan eksekusi kueri harus memindai tabel dan indeks yang jauh lebih kecil untuk menemukan data yang dibutuhkan. Terlepas dari seberapa efisien strategi indeks, memindai indeks untuk tabel berukuran 50GB akan selalu jauh lebih cepat daripada indeks untuk tabel berukuran 500GB. Ini juga berlaku untuk pemindaian tabel, karena terkadang pemindaian tabel tidak dapat dihindari.

Saat memperkenalkan tabel yang dipartisi ke perencana kueri, ada beberapa hal yang perlu diketahui dan dipahami tentang perencana kueri itu sendiri. Sebelum kueri apa pun benar-benar dijalankan, perencana kueri akan mengambil kueri dan merencanakan cara paling efisien untuk mengakses data. Dengan membagi data di tabel yang berbeda, perencana dapat memutuskan tabel apa yang akan diakses, dan tabel apa yang benar-benar diabaikan, berdasarkan isi setiap tabel.

Ini dilakukan dengan menambahkan batasan ke tabel terpisah yang menentukan data apa yang diizinkan di setiap tabel, dan dengan desain yang baik, kita dapat meminta perencana kueri memindai sebagian kecil data daripada keseluruhannya.

Haruskah Sebuah Tabel Dipartisi?

Mempartisi dapat secara drastis meningkatkan kinerja pada tabel jika dilakukan dengan benar, tetapi jika dilakukan salah atau saat tidak diperlukan, hal itu dapat memperburuk kinerja, bahkan tidak dapat digunakan.

Berapa besar mejanya?

Tidak ada aturan garis keras yang nyata tentang seberapa besar tabel harus sebelum mempartisi adalah pilihan, tetapi berdasarkan tren akses database, pengguna database dan administrator akan mulai melihat kinerja pada tabel tertentu mulai menurun seiring bertambahnya ukuran. Secara umum, partisi seharusnya hanya dipertimbangkan ketika seseorang mengatakan "Saya tidak bisa melakukan X karena tabelnya terlalu besar." Untuk beberapa host, 200 GB bisa menjadi waktu yang tepat untuk mempartisi, untuk yang lain, mungkin sudah waktunya untuk mempartisi ketika mencapai 1 TB.

Jika tabel ditentukan untuk menjadi "terlalu besar", saatnya untuk melihat pola akses. Baik dengan mengetahui aplikasi yang mengakses database, atau dengan memantau log dan membuat laporan kueri dengan sesuatu seperti pgBadger, kita dapat melihat bagaimana tabel diakses, dan bergantung pada bagaimana tabel diakses, kita dapat memiliki opsi untuk strategi partisi yang baik.

Untuk mempelajari lebih lanjut tentang pgBadger dan cara menggunakannya, silakan lihat artikel kami sebelumnya tentang pgBadger.

Apakah tabel mengasapi masalah?

Baris yang diperbarui dan dihapus menghasilkan tupel mati yang pada akhirnya perlu dibersihkan. Menyedot debu meja, baik secara manual atau otomatis, memeriksa setiap baris dalam tabel dan menentukan apakah akan direklamasi atau dibiarkan sendiri. Semakin besar tabel, semakin lama proses ini berlangsung, dan semakin banyak sumber daya sistem yang digunakan. Bahkan jika 90% dari tabel adalah data yang tidak berubah, itu harus dipindai setiap kali vakum dijalankan. Mempartisi tabel dapat membantu mengurangi tabel yang memerlukan penyedot debu menjadi yang lebih kecil, mengurangi jumlah data yang tidak berubah yang perlu dipindai, lebih sedikit waktu untuk menyedot debu secara keseluruhan, dan lebih banyak sumber daya sistem yang dibebaskan untuk akses pengguna daripada pemeliharaan sistem.

Bagaimana Data Dihapus, jika ada?

Jika data dihapus sesuai jadwal, katakanlah data yang lebih lama dari 4 tahun dihapus dan diarsipkan, ini dapat mengakibatkan pernyataan penghapusan yang membutuhkan waktu lama untuk dijalankan, dan seperti yang disebutkan sebelumnya, membuat baris mati yang perlu dikosongkan. Jika strategi partisi yang baik diterapkan, pernyataan DELETE multi-jam dengan pemeliharaan penyedot debu sesudahnya dapat diubah menjadi pernyataan DROP TABLE satu menit pada tabel bulanan lama tanpa pemeliharaan penyedot debu.

Bagaimana Seharusnya Tabel Dipartisi?

Kunci untuk pola akses ada di klausa WHERE dan kondisi JOIN. Setiap kali kueri menentukan kolom dalam klausa WHERE dan JOIN, ia memberi tahu database "ini adalah data yang saya inginkan". Sama seperti merancang indeks yang menargetkan klausa ini, strategi partisi bergantung pada penargetan kolom ini untuk memisahkan data dan membuat kueri mengakses partisi sesedikit mungkin.

Contoh:

  1. Tabel transaksi, dengan kolom tanggal yang selalu digunakan dalam klausa where.
  2. Tabel pelanggan dengan kolom lokasi, seperti negara tempat tinggal yang selalu digunakan dalam klausa where.

Kolom paling umum yang menjadi fokus untuk partisi biasanya adalah stempel waktu, karena biasanya sebagian besar data adalah informasi historis, dan kemungkinan akan memiliki data yang dapat diprediksi tersebar di berbagai pengelompokan waktu.

Menentukan Penyebaran Data

Setelah kita mengidentifikasi kolom mana yang akan dipartisi, kita harus melihat penyebaran data, dengan tujuan membuat ukuran partisi yang menyebarkan data secara merata di seluruh partisi turunan yang berbeda.

severalnines=# SELECT DATE_TRUNC('year', view_date)::DATE, COUNT(*) FROM website_views GROUP BY 1 ORDER BY 1;
 date_trunc |  count
------------+----------
 2013-01-01 | 11625147
 2014-01-01 | 20819125
 2015-01-01 | 20277739
 2016-01-01 | 20584545
 2017-01-01 | 20777354
 2018-01-01 |   491002
(6 rows)

Dalam contoh ini, kami memotong kolom stempel waktu menjadi tabel tahunan, menghasilkan sekitar 20 juta baris per tahun. Jika semua kueri kami menentukan tanggal, atau rentang tanggal, dan yang ditentukan biasanya mencakup data dalam satu tahun, ini mungkin strategi awal yang bagus untuk mempartisi, karena akan menghasilkan satu tabel per tahun , dengan jumlah baris per tabel yang dapat diatur.

Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

Membuat Tabel yang Dipartisi

Ada beberapa cara untuk membuat tabel yang dipartisi, namun kami akan fokus terutama pada jenis yang paling kaya fitur yang tersedia, partisi berbasis pemicu. Ini memerlukan pengaturan manual dan sedikit pengkodean dalam bahasa prosedural plpgsql agar berfungsi.

Ini beroperasi dengan memiliki tabel induk yang pada akhirnya akan menjadi kosong (atau tetap kosong jika itu adalah tabel baru), dan tabel anak yang MEMERIKSA tabel induk. Ketika tabel induk ditanyai, tabel anak juga mencari data karena INHERIT diterapkan ke tabel anak. Namun, karena tabel anak hanya berisi subset dari data induk, kami menambahkan CONSTRAINT pada tabel yang melakukan CHECK dan memverifikasi bahwa data cocok dengan apa yang diizinkan dalam tabel. Ini melakukan dua hal:Pertama ia menolak data yang bukan miliknya, dan kedua memberitahu perencana kueri bahwa hanya data yang cocok dengan KONSTRAIN PERIKSA ini yang diperbolehkan dalam tabel ini, jadi jika mencari data yang tidak cocok dengan tabel, jangan' bahkan tidak perlu repot mencarinya.

Terakhir, kami menerapkan pemicu ke tabel induk yang menjalankan prosedur tersimpan yang memutuskan tabel anak mana yang akan menyimpan data.

Buat Tabel

Membuat tabel induk sama seperti pembuatan tabel lainnya.

severalnines=# CREATE TABLE data_log (data_log_sid SERIAL PRIMARY KEY,
  date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
  event_details VARCHAR);
CREATE TABLE

Buat Tabel Anak

Membuat tabel anak serupa, tetapi melibatkan beberapa tambahan. Demi organisasi, kami akan membuat tabel anak kami ada dalam skema terpisah. Lakukan ini untuk setiap tabel anak, ubah detailnya sesuai dengan itu.

CATATAN:Nama urutan yang digunakan di nextval() berasal dari urutan yang dibuat induknya. Ini penting agar semua tabel anak menggunakan urutan yang sama.

severalnines=# CREATE SCHEMA part;
CREATE SCHEMA

severalnines=# CREATE TABLE part.data_log_2018 (data_log_sid integer DEFAULT nextval('public.data_log_data_log_sid_seq'::regclass),
  date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
  event_details VARCHAR)
 INHERITS (public.data_log);
CREATE TABLE

severalnines=# ALTER TABLE ONLY part.data_log_2018
    ADD CONSTRAINT data_log_2018_pkey PRIMARY KEY (data_log_sid);
ALTER TABLE

severalnines=# ALTER TABLE part.data_log_2018 ADD CONSTRAINT data_log_2018_date CHECK (date >= '2018-01-01' AND date < '2019-01-01');
ALTER TABLE

Buat Fungsi dan Pemicu

Terakhir, kami membuat prosedur tersimpan kami, dan menambahkan pemicu ke tabel induk kami.

severalnines=# CREATE OR REPLACE FUNCTION 
 public.insert_trigger_table()
  RETURNS trigger
  LANGUAGE plpgsql
 AS $function$
 BEGIN
     IF NEW.date >= '2018-01-01' AND NEW.date < '2019-01-01' THEN
         INSERT INTO part.data_log_2018 VALUES (NEW.*);
         RETURN NULL;
     ELSIF NEW.date >= '2019-01-01' AND NEW.date < '2020-01-01' THEN
         INSERT INTO part.data_log_2019 VALUES (NEW.*);
         RETURN NULL;
     END IF;
 END;
 $function$;
CREATE FUNCTION

severalnines=# CREATE TRIGGER insert_trigger BEFORE INSERT ON data_log FOR EACH ROW EXECUTE PROCEDURE insert_trigger_table();
CREATE TRIGGER

Ujilah

Sekarang setelah semuanya dibuat, mari kita uji. Dalam pengujian ini, saya telah menambahkan lebih banyak tabel tahunan yang mencakup 2013 - 2020.

Catatan:Tanggapan penyisipan di bawah ini adalah 'INSERT 0 0', yang berarti tidak memasukkan apa pun. Ini akan dibahas nanti di artikel ini.

severalnines=# INSERT INTO data_log (date, event_details) VALUES ('2018-08-20 15:22:14', 'First insert');
INSERT 0 0

severalnines=# SELECT * FROM data_log WHERE date >= '2018-08-01' AND date < '2018-09-01';
 data_log_sid |            date            | event_details
--------------+----------------------------+---------------
            1 | 2018-08-17 23:01:38.324056 | First insert
(1 row)

Itu ada, tetapi mari kita lihat perencana kueri untuk memastikan baris berasal dari tabel anak yang benar, dan tabel induk tidak mengembalikan baris sama sekali.

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log;
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..130.12 rows=5813 width=44) (actual time=0.016..0.019 rows=1 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.007..0.007 rows=0 loops=1)
   ->  Seq Scan on data_log_2015  (cost=0.00..21.30 rows=1130 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2013  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2014  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2016  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2017  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2018  (cost=0.00..1.02 rows=2 width=44) (actual time=0.005..0.005 rows=1 loops=1)
   ->  Seq Scan on data_log_2019  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2020  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
 Planning time: 0.373 ms
 Execution time: 0.069 ms
(12 rows)

Kabar baik, satu baris yang kami masukkan mendarat di tabel 2018, tempatnya. Namun seperti yang bisa kita lihat, kueri tidak menentukan klausa where menggunakan kolom tanggal, jadi untuk mengambil semuanya, perencana dan eksekusi kueri melakukan pemindaian berurutan pada setiap tabel.

Selanjutnya, mari kita uji menggunakan klausa where.

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log WHERE date >= '2018-08-01' AND date < '2018-09-01';
                                                                   QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..2.03 rows=2 width=44) (actual time=0.013..0.014 rows=1 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.007..0.007 rows=0 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
   ->  Seq Scan on data_log_2018  (cost=0.00..1.03 rows=1 width=44) (actual time=0.006..0.006 rows=1 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
 Planning time: 0.591 ms
 Execution time: 0.041 ms
(7 rows)

Disini kita dapat melihat bahwa query planner dan execution melakukan sekuensial scan pada dua tabel, tabel parent dan tabel anak untuk tahun 2018. Ada tabel anak untuk tahun 2013 - 2020, tetapi selain 2018 tidak pernah diakses karena klausa where memiliki rentang yang hanya dimiliki dalam tahun 2018. Perencana kueri mengesampingkan semua tabel lainnya karena CHECK CONSTRAINT menganggap data tidak mungkin ada di tabel tersebut.

Partisi Bekerja dengan Alat ORM Ketat atau Validasi Baris yang Disisipkan

Seperti disebutkan sebelumnya, contoh yang kami buat mengembalikan 'INSERT 0 0' meskipun kami menyisipkan baris. Jika aplikasi memasukkan data ke dalam tabel yang dipartisi ini bergantung pada verifikasi bahwa baris yang dimasukkan sudah benar, ini akan gagal. Ada perbaikan, tetapi menambahkan lapisan kompleksitas lain ke tabel yang dipartisi, sehingga dapat diabaikan jika skenario ini tidak menjadi masalah untuk aplikasi yang menggunakan tabel yang dipartisi.

Menggunakan Tampilan sebagai ganti tabel induk.

Perbaikan untuk masalah ini adalah membuat tampilan yang mengkueri tabel induk, dan mengarahkan pernyataan INSERT ke tampilan. Menyisipkan ke dalam tampilan mungkin terdengar gila, tetapi di situlah pemicu pada tampilan masuk.

severalnines=# CREATE VIEW data_log_view AS 
 SELECT data_log.data_log_sid,
     data_log.date,
     data_log.event_details
    FROM data_log;
CREATE VIEW

severalnines=# ALTER VIEW data_log_view ALTER COLUMN data_log_sid SET default nextval('data_log_data_log_sid_seq'::regclass);
ALTER VIEW

Membuat kueri tampilan ini akan terlihat seperti kueri tabel utama, dan klausa WHERE serta JOINS akan beroperasi seperti yang diharapkan.

Melihat Fungsi dan Pemicu Tertentu

Alih-alih menggunakan fungsi dan pemicu yang kami definisikan sebelumnya, keduanya akan sedikit berbeda. Perubahan dalam huruf tebal.

CREATE OR REPLACE FUNCTION public.insert_trigger_view()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
BEGIN
    IF NEW.date >= '2018-01-01' AND NEW.date < '2019-01-01' THEN
        INSERT INTO part.data_log_2018 VALUES (NEW.*);
        RETURN NEW;

    ELSIF NEW.date >= '2019-01-01' AND NEW.date < '2020-01-01' THEN
        INSERT INTO part.data_log_2019 VALUES (NEW.*);
        RETURN NEW;

    END IF;
END;
$function$;

severalnines=# CREATE TRIGGER insert_trigger INSTEAD OF INSERT ON data_log_view FOR EACH ROW EXECUTE PROCEDURE insert_trigger_view();

Definisi "INSTEAD OF" mengambil alih perintah insert pada tampilan (yang tidak akan berfungsi), dan menjalankan fungsi sebagai gantinya. Fungsi yang kami definisikan memiliki persyaratan yang sangat spesifik untuk melakukan 'RETURN NEW;' setelah penyisipan ke tabel anak selesai. Tanpa ini (atau melakukannya seperti yang kami lakukan sebelumnya dengan 'RETURN NULL') akan menghasilkan 'INSERT 0 0' alih-alih 'INSERT 0 1' seperti yang kami harapkan.

Contoh:

severalnines=# INSERT INTO data_log_view (date, event_details) VALUES ('2018-08-20 18:12:48', 'First insert on the view');
INSERT 0 1

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log_view WHERE date >= '2018-08-01' AND date < '2018-09-01';
                                                                   QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..2.03 rows=2 width=44) (actual time=0.015..0.017 rows=2 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.009..0.009 rows=0 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
   ->  Seq Scan on data_log_2018  (cost=0.00..1.03 rows=1 width=44) (actual time=0.006..0.007 rows=2 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
 Planning time: 0.633 ms
 Execution time: 0.048 ms
(7 rows)

severalnines=# SELECT * FROM data_log_view WHERE date >= '2018-08-01' AND date < '2018-09-01';
 data_log_sid |        date         |      event_details
--------------+---------------------+--------------------------
            1 | 2018-08-20 15:22:14 | First insert
            2 | 2018-08-20 18:12:48 | First insert on the view
(2 rows)

Pengujian aplikasi untuk 'jumlah baris' yang dimasukkan benar akan menemukan perbaikan ini berfungsi seperti yang diharapkan. Dalam contoh ini, kami menambahkan _view ke tampilan dan prosedur tersimpan kami, tetapi jika tabel ingin dipartisi tanpa ada pengguna yang mengetahui / perubahan aplikasi, maka kami akan mengganti nama tabel induk menjadi data_log_parent, dan memanggil tampilan dengan yang lama nama tabel induk.

Memperbarui baris dan mengubah nilai kolom yang dipartisi

Satu hal yang harus diperhatikan adalah jika melakukan pembaruan pada data di tabel yang dipartisi, dan mengubah nilai kolom menjadi sesuatu yang tidak diizinkan oleh batasan akan menghasilkan kesalahan. Jika jenis pembaruan ini tidak akan pernah terjadi, maka itu dapat diabaikan, tetapi jika memungkinkan, pemicu baru untuk proses UPDATE harus ditulis yang secara efektif akan menghapus baris dari partisi anak lama, dan memasukkan yang baru ke dalam partisi anak target baru.

Membuat Partisi Masa Depan

Membuat partisi masa depan dapat dilakukan dengan beberapa cara berbeda, masing-masing dengan kelebihan dan kekurangannya.

Pembuat Partisi Masa Depan

Program eksternal dapat ditulis untuk membuat partisi X kali sebelum dibutuhkan. Dalam contoh partisi yang dipartisi pada tanggal, partisi berikutnya yang diperlukan untuk dibuat (dalam kasus kami 2019) dapat diatur untuk dibuat sekitar bulan Desember. Ini bisa berupa skrip manual yang dijalankan oleh Administrator Basis Data, atau diatur agar cron menjalankannya saat diperlukan. Partisi tahunan berarti itu berjalan setahun sekali, namun partisi harian adalah umum, dan pekerjaan cron harian membuat DBA lebih bahagia.

Pembuat Partisi Otomatis

Dengan kekuatan plpgsql, kita dapat menangkap kesalahan jika mencoba memasukkan data ke partisi anak yang tidak ada, dan dengan cepat membuat partisi yang diperlukan, lalu mencoba memasukkan lagi. Opsi ini bekerja dengan baik kecuali dalam kasus di mana banyak klien yang berbeda memasukkan data yang sama pada saat yang sama, dapat menyebabkan kondisi balapan di mana satu klien membuat tabel, sementara yang lain mencoba membuat tabel yang sama dan mendapatkan kesalahan yang sudah ada. Pemrograman plpgsql yang cerdas dan canggih dapat memperbaikinya, tetapi apakah tingkat upaya itu sepadan atau tidak, masih diperdebatkan. Jika kondisi balapan ini tidak akan terjadi karena pola sisipan, maka tidak ada yang perlu dikhawatirkan.

Menjatuhkan Partisi

Jika aturan penyimpanan data menentukan bahwa data dihapus setelah jangka waktu tertentu, ini menjadi lebih mudah dengan tabel yang dipartisi jika dipartisi pada kolom tanggal. Jika kita ingin menghapus data yang berumur 10 tahun, bisa sesederhana:

severalnines=# DROP TABLE part.data_log_2007;
DROP TABLE

Ini jauh lebih cepat, dan lebih efisien daripada pernyataan 'HAPUS', karena tidak mengakibatkan tupel mati untuk dibersihkan dengan ruang hampa.

Catatan:Jika menghapus tabel dari pengaturan partisi, kode dalam fungsi pemicu juga harus diubah agar tidak mengarahkan tanggal ke tabel yang dijatuhkan.

Hal yang Perlu Diketahui Sebelum Mempartisi

Tabel partisi dapat menawarkan peningkatan kinerja yang drastis, tetapi juga dapat memperburuknya. Sebelum mendorong ke server produksi, strategi partisi harus diuji secara ekstensif, untuk konsistensi data, kecepatan kinerja, semuanya. Mempartisi tabel memiliki beberapa bagian yang bergerak, semuanya harus diuji untuk memastikan tidak ada masalah.

Ketika memutuskan jumlah partisi, sangat disarankan untuk menjaga jumlah tabel anak di bawah 1000 tabel, dan bahkan lebih rendah jika memungkinkan. Setelah jumlah tabel anak di atas ~1000, kinerja mulai menurun karena perencana kueri itu sendiri akhirnya membutuhkan waktu lebih lama hanya untuk membuat rencana kueri. Bukan hal yang aneh jika rencana kueri membutuhkan banyak detik, sedangkan eksekusi sebenarnya hanya membutuhkan beberapa milidetik. Jika melayani ribuan kueri dalam satu menit, beberapa detik dapat menghentikan aplikasi.

Prosedur tersimpan pemicu plpgsql juga bisa menjadi rumit, dan jika terlalu rumit, juga memperlambat kinerja. Prosedur tersimpan dijalankan sekali untuk setiap baris yang dimasukkan ke dalam tabel. Jika akhirnya melakukan terlalu banyak pemrosesan untuk setiap baris, sisipan bisa menjadi terlalu lambat. Pengujian kinerja akan memastikannya masih dalam kisaran yang dapat diterima.

Jadilah Kreatif

Tabel partisi di PostgreSQL bisa secanggih yang dibutuhkan. Alih-alih kolom tanggal, tabel dapat dipartisi pada kolom 'negara', dengan tabel untuk setiap negara. Partisi dapat dilakukan pada beberapa kolom, seperti kolom 'tanggal' dan 'negara'. Ini akan membuat prosedur tersimpan yang menangani penyisipan menjadi lebih rumit, tetapi ini 100% mungkin.

Ingat, tujuan dengan partisi adalah untuk memecah tabel yang sangat besar menjadi tabel yang lebih kecil, dan melakukannya dengan cara yang dipikirkan dengan matang untuk memungkinkan perencana kueri mengakses data lebih cepat daripada yang bisa dilakukan di tabel asli yang lebih besar.

Partisi Deklaratif

Di PostgreSQL 10 dan yang lebih baru, fitur partisi baru 'Declarative Partitioning' diperkenalkan. Ini adalah cara yang lebih mudah untuk menyiapkan partisi, namun memiliki beberapa batasan. Jika batasannya dapat diterima, kemungkinan akan bekerja lebih cepat daripada penyiapan partisi manual, tetapi sejumlah besar pengujian akan memverifikasi itu.

Dokumentasi postgresql resmi memiliki informasi tentang Partisi Deklaratif dan cara kerjanya. Ini baru di PostgreSQL 10, dan dengan PostgreSQL versi 11 di cakrawala pada saat penulisan ini, beberapa batasan diperbaiki, tetapi tidak semuanya. Seiring berkembangnya PostgreSQL, Partisi Deklaratif dapat menjadi pengganti penuh untuk partisi yang lebih kompleks yang dibahas dalam artikel ini. Sampai saat itu, Partisi Deklaratif mungkin menjadi alternatif yang lebih mudah jika tidak ada batasan yang membatasi kebutuhan partisi.

Batasan Pemisahan Deklaratif

Dokumentasi PostgreSQL membahas semua batasan dengan jenis partisi ini di PostgreSQL 10, tetapi gambaran umum yang bagus dapat ditemukan di The Official PostgreSQL Wiki yang mencantumkan batasan dalam format yang lebih mudah dibaca, serta mencatat mana yang telah diperbaiki. PostgreSQL 11 mendatang.

Tanya Komunitas

Administrator Basis Data di seluruh dunia telah merancang strategi partisi tingkat lanjut dan khusus untuk waktu yang lama, dan banyak dari kita berkumpul di IRC dan milis. Jika bantuan diperlukan untuk memutuskan strategi terbaik, atau hanya menyelesaikan bug dalam prosedur tersimpan, komunitas siap membantu.

  • IRC
    Freenode memiliki saluran yang sangat aktif bernama #postgres, tempat pengguna saling membantu memahami konsep, memperbaiki kesalahan, atau menemukan sumber daya lainnya.
  • Daftar Surat
    PostgreSQL memiliki beberapa milis yang dapat digabungkan. Pertanyaan / masalah yang lebih panjang dapat dikirim ke sini, dan dapat menjangkau lebih banyak orang daripada IRC pada waktu tertentu. Daftar tersebut dapat ditemukan di Situs Web PostgreSQL, dan daftar pgsql-general atau pgsql-admin adalah sumber yang bagus.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jenis stempel waktu mana yang harus saya pilih dalam database PostgreSQL?

  2. SQLAlchemy atau psycopg2?

  3. Aplikasi Boot Musim Semi macet di Hikari-Pool-1 - Memulai...

  4. Penyelaman Mendalam Vendor Cloud:PostgreSQL di AWS Aurora

  5. VACUUM PostgreSQL dan ANALISIS Tips Praktik Terbaik