🎉 Das neue Waldheim Customer Portal ist live – Zentrale Verwaltung für alle unsere Produkte!
Wir stellen vor: Das Customer Portal – Ihre zentrale Plattform zur Verwaltung von Lizenzen, Abonnements und Support für Ecodrive, Socialverse und Silvacore. Mit vollständiger Stripe-Integration, Multi-User-System und 2FA-Sicherheit.

Turbo für Angular: Wie ich PostgreSQL-Abfragen für Ladezeiten unter 100ms optimiere
Entdecken Sie meine Techniken zur Optimierung von PostgreSQL-Datenbankzugriffen, um die Performance Ihrer Angular-Anwendung drastisch zu verbessern.
Turbo für Angular: Wenn die Bremse in der Datenbank liegt
Ihre Angular-Anwendung ist nach allen Regeln der Kunst optimiert: Sie nutzen AOT-Kompilierung, Lazy Loading für Ihre Module und OnPush-Change-Detection. Trotzdem dauert das Laden der Startseite eine gefühlte Ewigkeit. Der Ladebalken kriecht, und die Nutzer werden ungeduldig. In vielen Fällen liegt die Ursache für ein langsames Frontend nicht im Frontend-Code selbst, sondern tief im Backend – in einer langsamen Datenbankabfrage. Eine einzige ineffiziente PostgreSQL-Abfrage kann die Ladezeit von Millisekunden auf Sekunden katapultieren.
Als Full-Stack-Entwickler, der sowohl die Angular- als auch die Go/PostgreSQL-Seite verantwortet, ist die Optimierung des gesamten Datenflusses meine Kernaufgabe. Das Ziel ist klar: Jede für den initialen Seitenaufbau kritische API-Anfrage muss in unter 100 Millisekunden beantwortet werden. In diesem Beitrag zeige ich Ihnen meine bewährten Techniken, mit denen ich PostgreSQL-Abfragen systematisch analysiere und optimiere, um Angular-Anwendungen blitzschnell zu machen.
Schritt 1: Den Schuldigen finden – EXPLAIN ANALYZE
Das wichtigste Werkzeug jedes PostgreSQL-Optimierers ist der Befehl EXPLAIN ANALYZE. Er führt eine Abfrage nicht nur aus, sondern gibt einen detaillierten Ausführungsplan zurück, der genau zeigt, wie PostgreSQL die Daten findet und wie lange jeder Schritt dauert.
- Die Praxis:
- Ich identifiziere die langsame API-Anfrage, die das Angular-Frontend ausbremst (z.B. über die Netzwerkanalyse im Browser).
- Ich finde die zugehörige SQL-Abfrage im Go-Backend-Code.
- Ich führe diese Abfrage direkt in einem SQL-Client (wie
psqloder DBeaver) aus, aber mitEXPLAIN ANALYZEvorangestellt.
Beispiel für eine langsame Abfrage:
EXPLAIN ANALYZE
SELECT *
FROM orders
JOIN customers ON orders.customer_id = customers.id
WHERE customers.email = 'test@example.com';Was ich im Output suche:
Seq Scan(Sequential Scan): Das ist oft ein rotes Tuch. Es bedeutet, PostgreSQL muss die gesamte Tabelle Zeile für Zeile durchlesen, um die Daten zu finden. Das ist bei großen Tabellen extrem langsam.- Hohe
costundactual time: Der Plan zeigt die geschätzten Kosten und die tatsächliche Ausführungszeit für jeden Schritt. Hohe Werte zeigen den Flaschenhals.
Schritt 2: Indizes – Das Inhaltsverzeichnis Ihrer Datenbank
Die häufigste Ursache für einen Seq Scan ist ein fehlender Index. Ein Index funktioniert wie das Inhaltsverzeichnis in einem Buch: Anstatt das ganze Buch durchzublättern, schaut die Datenbank im Index nach und springt direkt zur richtigen Seite.
- Meine Indexing-Strategie:
- Fremdschlüssel (
FOREIGN KEY): Ich stelle sicher, dass alle Spalten, die als Fremdschlüssel verwendet werden (im Beispiel obenorders.customer_id), einen Index haben. - Spalten in
WHERE-Klauseln: Alle Spalten, die häufig inWHERE-Klauseln zum Filtern verwendet werden (im Beispielcustomers.email), benötigen unbedingt einen Index. - Spalten in
JOIN-Bedingungen: Spalten, die fürJOINsverwendet werden, müssen indiziert sein.
- Fremdschlüssel (
Beispiel: Den richtigen Index erstellen:
-- Index für die E-Mail-Spalte, um die Suche zu beschleunigen
CREATE INDEX idx_customers_email ON customers(email);
-- Index für den Fremdschlüssel, um den JOIN zu beschleunigen
CREATE INDEX idx_orders_customer_id ON orders(customer_id);Führe ich EXPLAIN ANALYZE nach dem Erstellen dieser Indizes erneut aus, sollte der Plan statt eines Seq Scan einen viel schnelleren Index Scan oder Bitmap Index Scan zeigen.
Schritt 3: Abfragen umschreiben und optimieren
Manchmal ist nicht ein fehlender Index das Problem, sondern die Art, wie die Abfrage geschrieben ist.
- Vermeiden von
SELECT *: Ich frage immer nur die Spalten ab, die das Angular-Frontend auch wirklich benötigt.SELECT *überträgt unnötig viele Daten und kann die Nutzung von “Covering Indexes” verhindern. JOINsreduzieren: Oft werden zu viele Tabellen gejoined, obwohl die Daten auch mit wenigerJOINsoder einer zweiten, schlankeren Abfrage geholt werden könnten.- Komplexe Logik ins Backend verlagern: Anstatt komplexe Berechnungen in der Datenbank durchzuführen, verlagere ich diese oft in den Go-Service. Go ist dafür optimiert, während die Datenbank für das Speichern und Abrufen von Daten optimiert ist.
Schritt 4: Caching auf der Go-Ebene mit Redis
Selbst die schnellste Datenbankabfrage ist langsamer als ein Cache-Treffer. Für Daten, die sich nicht ständig ändern, implementiere ich eine Caching-Schicht im Go-Backend.
- Meine Caching-Strategie:
- Wenn eine Anfrage für bestimmte Daten (z.B. Produktdetails) eingeht, schaut der Go-Service zuerst in Redis nach.
- Cache Hit: Wenn die Daten in Redis gefunden werden, werden sie sofort zurückgegeben, ohne die PostgreSQL-Datenbank überhaupt zu kontaktieren.
- Cache Miss: Wenn die Daten nicht im Cache sind, wird die Abfrage an PostgreSQL gesendet. Das Ergebnis wird dann in Redis für zukünftige Anfragen gespeichert (mit einer angemessenen TTL, z.B. 5 Minuten) und an den Client zurückgegeben.
Konzeptioneller Go-Code:
package main
import (
"context"
"fmt"
"time"
"[github.com/redis/go-redis/v9](https://github.com/redis/go-redis/v9)"
"database/sql"
)
// ...
func getProductDetails(ctx context.Context, productID string, redisClient *redis.Client, db *sql.DB) (string, error) {
cacheKey := fmt.Sprintf("product:%s", productID)
// 1. Versuche, aus dem Cache zu lesen
val, err := redisClient.Get(ctx, cacheKey).Result()
if err == nil {
return val, nil // Cache Hit!
}
// 2. Cache Miss: Lese aus der Datenbank
var details string
err = db.QueryRowContext(ctx, "SELECT details FROM products WHERE id = $1", productID).Scan(&details)
if err != nil {
return "", err
}
// 3. Schreibe das Ergebnis in den Cache für die nächste Anfrage
redisClient.Set(ctx, cacheKey, details, 5*time.Minute)
return details, nil
}Fazit: Full-Stack-Performance ist Teamarbeit
Ein schnelles Frontend-Erlebnis ist das Ergebnis einer optimierten Zusammenarbeit zwischen Frontend, Backend und Datenbank. Eine langsame PostgreSQL-Abfrage kann die beste Angular-Optimierung zunichtemachen. Indem ich systematisch langsame Abfragen mit EXPLAIN ANALYZE identifiziere, die richtigen Indizes setze, Abfragen optimiere und eine intelligente Caching-Schicht implementiere, stelle ich sicher, dass die Daten so schnell wie möglich vom Backend zum Frontend gelangen. Das Ergebnis ist eine Angular-Anwendung, die sich nicht nur schnell anfühlt, sondern es auch wirklich ist.
Ist Ihre Angular-Anwendung langsamer als sie sein sollte, und Sie vermuten den Flaschenhals in der Datenbank? Ich biete Full-Stack-Performance-Analysen an. Lassen Sie uns gemeinsam Ihre API-Endpunkte und PostgreSQL-Abfragen durchleuchten und optimieren, um die Ladezeiten Ihrer Anwendung drastisch zu verkürzen. Kontaktieren Sie mich für ein Performance-Audit.
IT-Wissen, Trends & Insights – Mein Blog
Bleiben Sie auf dem Laufenden mit aktuellen Beiträgen zu DevSecOps, Webentwicklung, Smart Home und mehr.
Zum Blog
🎉 Das neue Waldheim Customer Portal ist live – Zentrale Verwaltung für alle unsere Produkte!
Wir stellen vor: Das Customer Portal – Ihre zentrale Plattform zur Verwaltung von Lizenzen, Abonnements und Support für Ecodrive, Socialverse und Silvacore. Mit vollständiger Stripe-Integration, Multi-User-System und 2FA-Sicherheit.

Die sichere Migration von PostgreSQL-Datenbanken: Mein Plan zur Vermeidung von Datenverlust
Ich präsentiere meinen detaillierten Migrationsplan für PostgreSQL, der Ausfallsicherheit und die Integrität der Daten in den Mittelpunkt stellt.

DSGVO-konformes Logging: Was ich bei der Protokollierung in Go-Anwendungen beachte
Ich erkläre die technischen und konzeptionellen Maßnahmen, die ich ergreife, um das Logging in Go-Services DSGVO-konform zu gestalten.

Angular und Content Security Policy (CSP): Eine praxisnahe Implementierung
Dieser Beitrag ist eine Schritt-für-Schritt-Anleitung, wie ich eine strikte Content Security Policy für eine komplexe Angular-Anwendung implementiere.