postgres inheritence partitioning - ghdrako/doc_snipets GitHub Wiki

The table inheritance for partitioning tables is the old way of table partition, before version 10, where you had to programmatically partition data with functions and triggers. However, this approach requires more maintenance and development effort than declarative partitions. The partition data is not automatically distributed to appropriate partitions after update of partition data.

With the inheritance method, you have to insert data into partitions by triggers. This method is for downward compatibility. This method does not update the partitions for the data movement by the upgrade command.

drop table if exists weather_data cascade;
CREATE TABLE weather_data (
    location_id   int not null,
    entrydate     date not null,
    avg_temp      int,
    rainfall      int
);
-- Create table for each day
     DO $$
DECLARE
    day DATE;
BEGIN
     FOR day IN SELECT generate_series('2024-06-01'::DATE, 
'2024-06-7'::DATE, '1 day'::INTERVAL)::DATE
    LOOP
         EXECUTE 'CREATE TABLE weather_data_' || to_char(day, 
'YYYYMMDD') || ' () INHERITS (weather_data)';
    END LOOP;
END $$;

Partition Insert Procedure

CREATE OR REPLACE FUNCTION weather_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF (NEW.entrydate >= '2024-06-01'AND NEW.entrydate < 
'2024-06-02') THEN
        INSERT INTO weather_data_20240601 VALUES (NEW.*);
       ELSIF (NEW.entrydate >= '2024-06-02' AND NEW.entrydate< 
'2024-06-03') THEN
        INSERT INTO weather_data_20240602 VALUES (NEW.*);
      ELSIF (NEW.entrydate >= '2024-06-03' AND NEW.entrydate< 
'2024-06-04') THEN
        INSERT INTO weather_data_20240603 VALUES (NEW.*);
     ELSIF (NEW.entrydate >= '2024-06-04' AND NEW.entrydate< 
'2024-06-05') THEN
        INSERT INTO weather_data_20240604 VALUES (NEW.*);
ELSIF (NEW.entrydate >= '2024-06-05' AND NEW.entrydate< 
'2024-06-06') THEN
        INSERT INTO weather_data_20240605 VALUES (NEW.*);
     ELSIF (NEW.entrydate >= '2024-06-06' AND NEW.entrydate< 
'2024-06-07') THEN
        INSERT INTO weather_data_20240606 VALUES (NEW.*);
    ELSE
         RAISE EXCEPTION 'Date out of range for weather_insert_
trigger() function!';
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER insert_weather_data_trigger
BEFORE INSERT ON weather_data
FOR EACH ROW EXECUTE FUNCTION weather_insert_trigger();

Constraint exclusion

Dla nowoczesnego partycjonowania(PG12+) parametr nieprzydatny

To parametr planisty zapytań w PostgreSQL, który mówi optymalizatorowi, czy może pominąć niektóre tabele/podtabele przy wykonywaniu zapytania, na podstawie ograniczeń (constraints).

CREATE TABLE faktury (
  id serial,
  data date,
  amount int
);

CREATE TABLE faktury_2023_01 (
  CHECK (data >= '2023-01-01' AND data < '2023-02-01')
) INHERITS (faktury);

CREATE TABLE faktury_2023_01 (
  CHECK (data >= '2023-02-01' AND data < '2023-03-01')
) INHERITS (faktury);

SELECT * FROM faktury WHERE data = '2023-01-10';

Aby planista(optymalizator) mogl odrzucic niepotrzebne partycje i szukac tylko w faktury_2023_01 potrzebne jest ustawienie constraint exclusion

Wartości constraint_exclusion

  • off – nie pomija niczego (wszystkie partycje brane pod uwagę),
  • on – pomija na podstawie constraintów w zapytaniach niezależnie od typu zapytania (SELECT, INSERT, UPDATE),
  • partition – domyślne od PostgreSQL 12; pomija tylko przy klasycznym partycjonowaniu (PARTITION BY).

Set parameter constraint exclusion to on or partition. If WHERE clause contain partition key optimizer using check constraint to remove partition from scaning

select * from pg_setting where name = 'constraint_exclusion';