Files
it-know-how/datenbanken/Materialized Views.md
T

12 KiB
Raw Blame History

#datenbank

➡️ #Zusammenfassung


1. Grundidee: Was ist eine Materialized View?

Eine Materialized View (materialisierte Sicht) ist vereinfacht gesagt:

Eine gespeicherte Ergebnistabelle einer Abfrage, die regelmäßig aktualisiert wird.

Im Unterschied zu einer „normalen“ View, die bei jedem Zugriff die zugrunde liegende Abfrage neu ausführt, werden bei einer Materialized View:

  • die Daten der Abfrage physisch gespeichert (wie in einer Tabelle),
  • und später wiederverwendet, ohne jedes Mal die komplette Abfrage neu berechnen zu müssen.

Du kannst dir das vorstellen wie einen vorgeberechneten Bericht, der als echte Tabelle im System liegt, aber technisch aus einer oder mehreren anderen Tabellen abgeleitet ist.

Typische Verwendung:

  • Große Tabellen
  • Aufwendige Joins
  • Aggregationen (SUM, COUNT, AVG, …)
  • Reporting & Analytics

2. Abgrenzung zu verwandten Begriffen

2.1 Normale View vs. Materialized View

View (logische Sicht):

  • Ist nur eine gespeicherte Abfrage.
  • Speichert selbst keine Daten.
  • Beim SELECT auf die View wird die zugrunde liegende Abfrage jedes Mal neu ausgeführt.
  • Vorteil: Immer aktuell, kein Speicheraufwand.
  • Nachteil: Kann bei komplexen Abfragen langsam sein.

Materialized View:

  • Ist eine physisch gespeicherte Tabelle, die aus einer Abfrage berechnet wurde.
  • Beim SELECT werden die vorgehaltenen Daten gelesen (schnell).
  • Muss explizit aktualisiert („refreshed“) werden.
  • Vorteil: Schnelle Abfragen, vor allem bei komplexen Berechnungen.
  • Nachteil: Daten können veraltet sein, zusätzlicher Speicher & Wartung.

2.2 Materialized View vs. Tabelle

Normale Tabelle:

  • Daten werden direkt in diese Tabelle geschrieben (INSERT, UPDATE, DELETE).
  • Struktur (Schema) ist unabhängig; die Tabelle „gehört sich selbst“.

Materialized View:

  • Wird aus anderen Tabellen abgeleitet (Definition durch SELECT).
  • Man schreibt normalerweise nicht direkt hinein, sondern nur in die Basistabellen.
  • Die Materialized View wird über einen Refresh-Mechanismus aktualisiert.

2.3 Materialized View vs. Cache

Ein Cache (z.B. im Application Server):

  • Hält Daten im Speicher, typischerweise kurzfristig.
  • Wird meist von der Anwendung gesteuert.
  • Ist oft flüchtig (z.B. bei Neustart weg).

Materialized View:

  • Ist Teil der Datenbank, persistent auf Disk.
  • Wird durch die Datenbank verwaltet.
  • Kann komplexere Konsistenz- und Refresh-Strategien nutzen.

2.4 Materialized View vs. Index

Index:

  • Beschleunigt den Zugriff auf bestehende Daten einer Tabelle.
  • Speichert typischerweise Schlüsselwerte und Zeiger auf die Tabelle.
  • Berechnet keine neuen Inhalte, sondern hilft, vorhandene schneller zu finden.

Materialized View:

  • Enthält eigene Daten, die Ergebnis einer Abfrage sind (z.B. Summen, Gruppierungen).
  • Kann zusätzlich selbst Indexe haben.

2.5 Datenbanken und Begriffe

Verschiedene Systeme nutzen leicht unterschiedliche Begriffe:

  • PostgreSQL: MATERIALIZED VIEW
  • Oracle: MATERIALIZED VIEW (sehr ausgereifte Funktionen)
  • SQL Server: Kein direkter Begriff, aber Indexed Views sind sehr ähnlich
  • MySQL: Keine echte Materialized View, aber man kann das Verhalten nachbauen (z.B. mit Triggern, geplanten Jobs, Tabellen)

3. Welche Probleme werden durch Materialized Views gelöst?

3.1 Performance bei komplexen Abfragen

Wenn du häufig dieselbe komplexe Abfrage ausführst, kostet das jedes Mal viel Rechenzeit:

  • Viele Joins über große Tabellen
  • Aggregationen (SUM, COUNT, MAX, …)
  • Filter auf komplizierten Kombinationen

Eine Materialized View berechnet diese Abfrage einmal (oder in festen Intervallen) und speichert das Ergebnis. Spätere Abfragen greifen nur noch auf die fertige Ergebnismenge zu.

Beispiel:

Du hast einen Online-Shop mit Tabellen:

  • orders (Bestellungen)
  • order_items (Bestellpositionen)
  • products (Produkte)
  • customers (Kunden)

Du willst regelmäßig wissen: Wie viel Umsatz pro Kunde pro Monat?

Ohne Materialized View:

SELECT
    c.customer_id,
    date_trunc('month', o.order_date) AS month,
    SUM(oi.quantity * oi.unit_price) AS revenue
FROM customers c
JOIN orders o        ON o.customer_id = c.customer_id
JOIN order_items oi  ON oi.order_id = o.order_id
GROUP BY c.customer_id, date_trunc('month', o.order_date);

Diese Abfrage kann bei Millionen Zeilen sehr langsam sein, besonders wenn sie viele Nutzer gleichzeitig ausführen.

Mit Materialized View:

CREATE MATERIALIZED VIEW mv_customer_monthly_revenue AS
SELECT
    c.customer_id,
    date_trunc('month', o.order_date) AS month,
    SUM(oi.quantity * oi.unit_price) AS revenue
FROM customers c
JOIN orders o        ON o.customer_id = c.customer_id
JOIN order_items oi  ON oi.order_id = o.order_id
GROUP BY c.customer_id, date_trunc('month', o.order_date);

Einfache Abfrage darauf:

SELECT * FROM mv_customer_monthly_revenue
WHERE month = '2025-01-01';

Das ist meist sehr schnell, da nur noch fertige Zeilen gelesen werden.

3.2 Entlastung der Primärtables

Wenn viele Nutzer komplexe Analysen auf den operativen Tabellen ausführen, kann das:

  • den Datenbankserver stark belasten,
  • Transaktionen verlangsamen,
  • das Online-System (z.B. Shop) spürbar ausbremsen.

Materialized Views dienen hier als eine Art vorgefertigtes Reporting-Layer, das:

  • weniger Schreiboperationen hat,
  • stark komprimiert / aggregiert sein kann,
  • unabhängig indexiert werden kann.

3.3 Zugriff auf entfernte Daten (z.B. Data Warehouse)

In manchen Systemen kann eine Materialized View Daten aus anderen Datenbanken oder externen Quellen einbinden. Damit können z.B.:

  • Daten aus mehreren Systemen
  • in einer lokal gespeicherten, performanten Sicht zusammengefasst werden.

4. Welche Herausforderungen und Nachteile gibt es?

4.1 Datenaktualität (Freshness)

Materialized Views sind nicht automatisch immer aktuell.

Typische Arten des Refresh:

  1. Maneller Refresh
    Du rufst selbst etwas auf wie:

    REFRESH MATERIALIZED VIEW mv_customer_monthly_revenue;
    
  2. Geplanter Refresh (z.B. jede Stunde/Tageswechsel)
    Über Scheduler/Jobs: „Führe jede Nacht um 3 Uhr einen Refresh aus“.

  3. On Commit / nahezu in Echtzeit (je nach DB)
    Bei bestimmten Systemen können Materialized Views nach Änderungen an den Basistabellen automatisch aktualisiert werden.

Konsequenz:
Es gibt immer einen Trade-off zwischen:

  • Aktualität (häufig refresht → näher an „Echtzeit“)
  • Performance/Belastung (jeder Refresh ist teils teuer)

4.2 Konsistenz und Komplexität

Bei vielen Materialized Views, die sich überlappen oder von anderen Views abhängen, kann es kompliziert werden:

  • In welcher Reihenfolge refresht man?
  • Was passiert, wenn eine Quelle fehlerhaft ist?
  • Wie geht man mit teilweisen Refreshes um?

4.3 Speicherbedarf

Materialized Views brauchen zusätzlichen Speicher, da sie Daten duplizieren:

  • Daten sind in den Basistabellen vorhanden
  • plus noch einmal in den Materialized Views

Je nach Anzahl und Detailgrad kann das signifikant sein.

4.4 Schreibaufwand auf Basistabellen (indirekt)

Wenn Materialized Views sehr häufig aktualisiert werden:

  • können Inserts/Updates auf Basistabellen indirekt langsamer werden,
  • weil der Refresh-Prozess Ressourcen frisst (z.B. CPU, I/O, Locks).

Bei Systemen mit „Refresh on Commit“ müssen evtl. zusätzliche Metadaten gepflegt werden, um Änderungen nachvollziehbar zu machen.

4.5 Komplexität im Design und Betrieb

  • Man muss Entscheidungen treffen:

    • Welche Abfragen lohnen sich als Materialized View?
    • Wie oft sollten sie aktualisiert werden?
    • Wer ist verantwortlich für Monitoring und Fehlerbehandlung?
  • Bei Änderungen am Schema (z.B. Spalten hinzufügen) muss oft:

    • die Materialized View angepasst
    • oder neu aufgebaut werden.

5. Praxisnahe Beispiele

5.1 Reporting im E-Commerce

Stell dir einen Online-Shop vor, der täglich Tausende Bestellungen hat. Das Management möchte im Dashboard sehen:

  • Umsatz pro Tag
  • Top-10-Produkte pro Woche
  • Anzahl neuer Kunden pro Monat

Ohne Materialized Views würden diese Reports bei jedem Aufruf heavy Queries auf großen Tabellen ausführen.

Mit Materialized Views:

  1. mv_daily_revenue
    Umsätze pro Tag

    CREATE MATERIALIZED VIEW mv_daily_revenue AS
    SELECT
        date_trunc('day', o.order_date) AS day,
        SUM(oi.quantity * oi.unit_price) AS revenue
    FROM orders o
    JOIN order_items oi ON oi.order_id = o.order_id
    GROUP BY date_trunc('day', o.order_date);
    
  2. mv_weekly_top_products
    Top-Produkte je Woche

    CREATE MATERIALIZED VIEW mv_weekly_top_products AS
    SELECT
        date_trunc('week', o.order_date) AS week,
        oi.product_id,
        SUM(oi.quantity) AS total_quantity
    FROM orders o
    JOIN order_items oi ON oi.order_id = o.order_id
    GROUP BY date_trunc('week', o.order_date), oi.product_id;
    
  3. mv_monthly_new_customers
    Neue Kunden pro Monat

    CREATE MATERIALIZED VIEW mv_monthly_new_customers AS
    SELECT
        date_trunc('month', c.created_at) AS month,
        COUNT(*) AS new_customers
    FROM customers c
    GROUP BY date_trunc('month', c.created_at);
    

Diese Views kannst du z.B. jede Nacht aktualisieren, da sich historische Daten nicht mehr ändern.

5.2 Data Warehouse / BI

In einem Data Warehouse gibt es oft:

  • große „Faktentabellen“ (z.B. fact_sales mit hunderten Millionen Zeilen),
  • Dimensionstabellen (Kunde, Produkt, Region).

Materialized Views können hier als „Summary Tables“ dienen, z.B.:

  • Verkäufe pro Region und Monat
  • Verkäufe pro Produktkategorie und Quartal

Analysten müssen dann nicht mehr auf die komplette Faktentabelle zugreifen, sondern nur noch auf relativ kleine, aggregierte Materialized Views.

5.3 Teilweise Aktualisierung (Incremental Refresh)

Fortgeschrittene Systeme (z.B. Oracle) können Materialized Views inkrementell aktualisieren: Es werden nur die Änderungen seit dem letzten Stand eingerechnet, statt alles komplett neu zu berechnen. Das spart enorm Zeit und Ressourcen, ist aber vom Setup her komplexer.


6. Typische Strategien und Best Practices

  1. Nur für „schwere“ Abfragen nutzen
    Materialized Views lohnen sich insbesondere, wenn:

    • die Abfrage sehr teuer ist,
    • die Daten sich nicht „jede Sekunde“ ändern,
    • die Ergebnisse häufig angefragt werden.
  2. Refresh-Frequenz bewusst wählen

    • Nahe Echtzeit notwendig? → Häufigerer Refresh, mehr Last
    • Reine Reports (z.B. täglich) → nächtlicher Refresh reicht oft
  3. Materialized Views benennen und dokumentieren

    • Sinnvolle Namen (mv_...)
    • Dokumentation: Welche Abfrage? Wie wird refresht? Wer nutzt sie?
  4. Indexe auf Materialized Views setzen

    • Genau wie bei normalen Tabellen können Indexe Abfragen weiter beschleunigen:
    CREATE INDEX idx_mv_daily_revenue_day
        ON mv_daily_revenue (day);
    
  5. Monitoring

    • Refresh-Zeiten messen
    • Fehler beim Refresh protokollieren
    • Speicherverbrauch im Blick behalten

Zusammenfassung

  • Materialized Views sind gespeicherte (materialisierte) Ergebnisse von Abfragen, die wie Tabellen genutzt werden können.
  • Sie dienen vor allem zur Performance-Steigerung bei komplexen oder häufig ausgeführten Abfragen und zur Entlastung der operativen Tabellen.
  • Gegenüber normalen Views:
    • schneller beim Lesen,
    • aber nicht automatisch aktuell sie müssen refresht werden.
  • Herausforderungen:
    • Datenaktualität (wie oft refresht man?),
    • zusätzlicher Speicherverbrauch,
    • Komplexität in Design und Wartung.
  • Typische Einsatzgebiete:
    • Reporting, Analytics, Dashboards,
    • Data Warehousing,
    • Aggregationen über große Datenmengen.