Datenbank entlastet - Query-Zeiten halbiert

JSONB-Neustrukturierung in docobj_json, Index-Redesign und gezielte Migration – begleitet von einem Komplettumbau der Perl-Such- & Filterlogik.

Datenbank entlastet - Query-Zeiten halbiert

Ergebnisse

  • Speicherbedarf insgesamt um 32 % gesenkt
  • +50 % Performance, −90 % Tabellenvolumen

Metriken stammen aus den ursprünglichen Messungen/Artefakten (EXPLAIN ANALYZE Auswertungen und Vergleichsberichte).

Ausgangslage

Das Dokumentenarchiv stützte sich primär auf eine historisch gewachsene Tabelle docobj. Ein ungünstiges Datenmodell, wenig selektive Indizes und gewachsene Workarounds führten zu intransparenten Abfragepfaden, hohem Speicherverbrauch und inkonsistenten Ergebnissen.

Ansatz & Architektur

Wir führten eine neue Tabelle docobj_json ein und organisierten Daten in JSONB-Feldern neu. Damit ließen sich Hot-Paths vereinfachen und redundante Felder abbauen. Auf Basis von PostgreSQL 9.6 migrierten wir schrittweise Lese- und Schreibpfade, bauten neue Indizes concurrently auf und verlagerten die Suche auf stabilere, selektive Keys.

Konkret (vereinfacht)
-- Neue Struktur für schnellere Reads
CREATE TABLE docobj_json (
  id           bigserial PRIMARY KEY,
  obj_id       bigint NOT NULL,
  created_at   timestamptz NOT NULL DEFAULT now(),
  payload      jsonb NOT NULL  -- neu strukturierte JSONB-Daten
);

-- Selektive Indizes (Schattenerzeugung ohne Lock)
CREATE INDEX CONCURRENTLY idx_docobj_json_obj_id ON docobj_json (obj_id);
CREATE INDEX CONCURRENTLY idx_docobj_json_created ON docobj_json (created_at DESC);
CREATE INDEX CONCURRENTLY idx_docobj_json_gin ON docobj_json USING gin (payload jsonb_path_ops);

-- Beispiel für extrahierten Hot-Key (Flattening)
ALTER TABLE docobj_json ADD COLUMN project_id bigint;
UPDATE docobj_json
  SET project_id = (payload -> 'meta' ->> 'project_id')::bigint
  WHERE project_id IS NULL;
CREATE INDEX CONCURRENTLY idx_docobj_json_project ON docobj_json (project_id);

Ziel: eindeutige Schlüssel für Filter & Sortierung, bessere Kardi\-nalität und stabilere Planner-Entscheidungen.

Analyse & Messung

Abfragepläne wurden mit EXPLAIN (ANALYZE, BUFFERS) erhoben und bei explain.depesz.com visualisiert und verglichen. So ließen sich teure Seq-Scans, falsche Join-Reihenfolgen und überschätzte Selektivitäten nachvollziehen und gezielt beheben.

Perl-Refactoring: Suche & CRUD

Die Such- und Filterlogik (Perl) wurde grundlegend neu geschrieben (Dokumentenarchiv, vollständiges CRUD). Vorher umfasste der Code ca. 4.000 Zeilen; zahlreiche Workarounds basierten auf längst behobenen Altfehlern. Nach dem Umbau war die Suche präziser, robuster und deutlich schneller.

Qualitätssicherung

  • Unit- & Integrations-Tests als Black-Box gegen definierte Query-Sets
  • pgTap für DB-nahe Tests (Constraints, Views, Funktionen)
  • Vorher/Nachher-Vergleiche identischer Abfragen, reproduzierbar dokumentiert

Change Management

Während der Migration traten „Features“ zutage, die ursprünglich aus Bugs entstanden waren – nach Bereinigung verhielten sich Teilbereiche zunächst anders. Wir haben diese Fälle gemeinsam mit dem Team fachlich neu bewertet, sauber abgebildet und belastbar getestet. Ergebnis: weniger Komplexität, weniger Sonderfälle – und bessere, nachvollziehbare Ergebnisse.

Was heute anders ist

Die Datenhaltung ist klarer, Abfragen sind im Schnitt schneller, und der Speicherbedarf ist signifikant gesunken. Neue Anforderungen lassen sich risikoarm integrieren – dank konsistenter Tests, Messungen und dokumentierter Umschaltpunkte.

Kurzinfo

Dauer

ca. 12 Monate (laufender Umbau)

Rolle

DB-Design & Tuning · Perl-Refactoring · Teststrategie (pgTap)

Werkzeuge

PostgreSQL 9.6, EXPLAIN (ANALYZE), explain.depesz.com, pgTap, Perl, Bash