Monatlich Range-partitionierte Tabelle anlegen (Partitionen in einer Schleife erzeugen)
PostgreSQLPartitionierungBefehl
CREATE TABLE sales (
id bigint GENERATED ALWAYS AS IDENTITY,
created_at date NOT NULL,
customer_id bigint NOT NULL,
amount numeric(12,2),
PRIMARY KEY (id, created_at)
) PARTITION BY RANGE (created_at);
-- An index defined on the parent propagates to all partitions automatically
CREATE INDEX sales_customer_id_idx ON sales (customer_id);
-- 12 monthly partitions for 2026
DO $$
DECLARE
m date;
BEGIN
FOR m IN SELECT generate_series(date '2026-01-01', date '2026-12-01', interval '1 month')::date LOOP
EXECUTE format(
'CREATE TABLE IF NOT EXISTS %I PARTITION OF sales FOR VALUES FROM (%L) TO (%L)',
'sales_' || to_char(m, 'YYYY_MM'), m, (m + interval '1 month')::date);
END LOOP;
END $$;
-- Hierarchy, bounds and sizes
SELECT t.relid::regclass AS partition_name,
t.parentrelid::regclass AS parent,
t.isleaf,
t.level,
pg_get_expr(c.relpartbound, c.oid) AS bounds,
pg_size_pretty(pg_total_relation_size(t.relid)) AS total_size
FROM pg_partition_tree('sales') t
JOIN pg_class c ON c.oid = t.relid
ORDER BY t.level, bounds;Was es tut
Legt eine per RANGE auf einer Datumsspalte partitionierte Parent-Tabelle an, einen Index, der sich auf jede Partition überträgt, und in einer Schleife 12 Monatspartitionen; listet dann die Hierarchie mit Grenzen und Größen.
Wann einsetzen
Für große, ständig wachsende Tabellen, die regelmäßig alte Daten entfernen (DETACH/DROP) oder deren Abfragen meist nach Datumsbereich filtern (Bestellungen, Logs, Zeitreihen).
Vorsicht
Auf einer partitionierten Tabelle müssen PRIMARY-KEY-/UNIQUE-Constraints den Partitionsschlüssel enthalten (es gibt keine globalen Unique-Indizes). Die Untergrenze ist inklusiv, die Obergrenze exklusiv (FROM inklusiv, TO exklusiv). Ohne einen Job, der künftige Partitionen vorab anlegt (pg_cron, pg_partman), schlagen INSERTs außerhalb des Bereichs fehl. Tausende Partitionen erhöhen Planungszeit und Sperr-Overhead. CREATE INDEX CONCURRENTLY wird auf der Parent-Tabelle nicht unterstützt: Nutze CREATE INDEX ... ON ONLY auf der Parent-Tabelle, CREATE INDEX CONCURRENTLY auf jeder Partition und dann ALTER INDEX ... ATTACH PARTITION.
Verwandte Einträge
- Vorbereitete Tabelle mit kurzer Sperre als Partition einhängen (ATTACH PARTITION)
- Alte Partition aushängen, ohne den Live-Betrieb zu blockieren (DETACH CONCURRENTLY)
- Falle Default-Partition: neue Partition scheitert mit 'would be violated by some row'
- Prüfen, ob Partition Pruning funktioniert (Planungs- und Laufzeit)
- Anlegen und Aufbewahrung von Partitionen mit pg_partman automatisieren