Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn Sie eine Anwendung auf Azure Database for PostgreSQL flexiblen Server erstellen, ist das Hinzufügen einer Zwischenspeicherungsebene eine der effektivsten Methoden, um die Reaktionszeiten zu verbessern, die Auslastung ihrer Datenbank zu verringern und die Resilienz zu erhöhen. Durch häufiges Lesen von Daten aus einem Speichercache sendet Ihre Anwendung weniger Abfragen an PostgreSQL. Das bedeutet eine geringere CPU- und IOPS-Auslastung, sodass Sie mit einer kleineren Recheninstanzklasse auskommen, Lesevorgänge skalieren können, ohne den Server hochzuskalieren, und Verkehrsspitzen abfangen können. Ein Cache kann auch Resilienz hinzufügen. Wenn PostgreSQL kurzzeitig ausfällt, können Anfragen, die auf Daten zugreifen, die sich bereits im Cache befinden, weiterhin erfolgreich verarbeitet werden, sodass Lesezugriffe verfügbar bleiben, während sich die Datenbank erholt.
In diesem Artikel können Sie entscheiden, wann das Zwischenspeichern hilft und welches Muster zu Ihrer Anwendung passt. Anschließend werden vier Cachingmuster in Python (cache-aside, reference-data prefetching, write-through und event-driven) unter Verwendung von Azure Managed Redis, der Bibliotheken redis und psycopg sowie der Microsoft Entra ID-Authentifizierung implementiert.
Wann ein Cache hinzugefügt werden soll
PostgreSQL speichert bereits häufig verwendete Datenseiten im Puffercache zwischen und profitiert auch vom Dateicache des Betriebssystems. Diese Caches ermöglichen wiederholten Zugriff schneller, teilen jedoch den auf dem Datenbankserver zugewiesenen Arbeitsspeicher mit der Abfrageausführung und anderen Prozessen. Ihre Inhalte müssen nach bestimmten Wartungs- und Failover-Vorgängen ebenfalls wieder aktiviert werden.
Sie können mehr Cachekapazität für die Datenbank erhalten, indem Sie zu einer Computeoption mit mehr Arbeitsspeicher hochskalieren. Sie können auch die Einstellungen für den PostgreSQL-Speicher optimieren, aber das Zuordnen von mehr Arbeitsspeicher zum Puffercache lässt weniger für die Abfrageausführung und das Betriebssystem zu. Testen Sie Änderungen am Speicher sorgfältig, um Speichermangel zu vermeiden.
Azure Managed Redis ergänzt diese nativen Caches. Es speichert ausgewählte Anwendungsdaten und Abfrageergebnisse außerhalb des Datenbankservers, bietet Zugriff auf zeitkritische Lesepfade mit geringerer Latenz und kann zwischengespeicherte Lesevorgänge verfügbar halten, während PostgreSQL den Cache wiederherstellen oder warmt. Verwenden Sie sie, wenn diese Vorteile die hinzugefügte Anwendungslogik und einen anderen Dienst für den Betrieb rechtfertigen. Es ersetzt PostgreSQL nicht als Quelle der Wahrheit.
Das Hinzufügen eines externen Caches wie Azure Verwaltete Redis hilft am meisten, wenn Ihre Workload die folgenden Merkmale aufweist:
- Leseschwere Zugriffsmuster. Dieselben Zeilen werden viel häufiger gelesen, als sie sich ändern, z. B. Produktkataloge, Benutzerprofile, Konfigurationsdaten oder Referenztabellen.
- Teure oder wiederholte Abfragen. Aggregationen, Verknüpfungen oder berechnete Ergebnisse, deren Erstellung aufwendig ist, die aber über kurze Zeiträume stabil sind.
- Latenzempfindliche Endpunkte. Benutzerseitige Vorgänge, bei denen ein Lesevorgang im Arbeitsspeicher (unter einer Millisekunde) einem Datenbank-Roundtrip vorzuziehen ist.
- Vorhersehbare Spitzen. Saisonaler oder ereignisgesteuerter Traffic, bei dem Caching Last abfängt, die Sie andernfalls zur Skalierung der Rechenkapazität zwingen würde.
- Wartung und Ausfallsensitivität. Lesepfade, die konstante Antwortzeiten erfordern, während eine PostgreSQL-Instanz nach einem Wartungs- oder Failover-Vorgang ihren Cache wiederherstellt oder aktiviert.
Das Zwischenspeichern hilft weniger für schreibintensive Workloads, Daten, die immer transaktionskonsensant sein müssen, oder Abfragen, die bereits schnell und selten wiederholt sind.
Zwischenspeicherungsmuster
In diesem Artikel wird ein Einzelhandelsgeschäft als durchgängiges Beispiel verwendet. Verschiedene Teile der App profitieren von unterschiedlichen Cachemustern. In den folgenden Abschnitten werden die ersten vier Muster in Python implementiert. Der Artikel beschreibt Sitzungs- und Zustandsablade- und Zwischenspeicherungsmuster mit mehreren Regionen, stellt jedoch keine Codeimplementierungen bereit.
| Schema | So funktioniert es | Im Ladenlokal |
|---|---|---|
| Cache-Aside (Lazy Loading) | Die Anwendung überprüft zuerst den Cache. Bei einem Miss liest es aus PostgreSQL und füllt dann den Cache auf. | Produktkatalog- und Detailseiten, auf denen einige beliebte Artikel am häufigsten gelesen werden. |
| Vorabladen von Referenzdaten | Stabile Daten werden vorab in den Cache geladen und aktualisiert, sobald sich die Quelle ändert, anstatt erst bei einem Cache-Fehler. | Kategorien, Marken und Versandkonfigurationen. |
| Write-Through | Die Anwendung schreibt im selben Vorgang in den Cache und nach PostgreSQL und hält beide konsistent. | Preis- und Bestandsaktualisierungen, die sofort sichtbar sein müssen. |
| Ereignisgesteuerte Ungültigheit | Cacheeinträge werden als Reaktion auf Datenänderungsereignisse aktualisiert oder ungültig gemacht, statt über einen Timer. | Auftragsstatus während der Auftragserfüllung. |
| Sitzungs- und Zustands-Offloading | Der vorübergehende Zustand befindet sich im Cache anstelle der Datenbank. | Warenkörbe und Benutzersitzungen. |
| Regionenübergreifendes Caching | Ein Cache in jeder Region dient lokalen Lesevorgängen, die mit aktiver Georeplikation synchronisiert werden. | Eine globale Storefront, die Käufer in mehreren Regionen bedient. |
Prerequisites
- Ein Azure-Konto mit einem aktiven Abonnement. Kostenlos ein Konto erstellen.
- Eine Azure Database for PostgreSQL flexible Serverinstanz mit aktivierter Microsoft Entra Authentifizierung. Informationen zum Erstellen eines Servers finden Sie unter Erstellen eines Azure Database for PostgreSQL flexiblen Servers.
- Eine Azure Managed Redis Instanz. Informationen zum Erstellen einer Instanz finden Sie unter Erstellen einer Azure verwalteten Redis-Instanz. Erstellen Sie es in derselben Region wie Ihr PostgreSQL-Server (und für die Produktion dasselbe virtuelle Netzwerk), um die Latenz zu minimieren.
- Datenzugriff für Ihre Entwickler- oder Anwendungsidentität auf beiden Diensten: ein Microsoft-Entra-Administrator oder eine Rolle für den PostgreSQL-Server sowie die Zuweisung einer Redis-Zugriffsrichtlinie für den Cache. Siehe die Microsoft Entra-Authentifizierung für Azure Database for PostgreSQL und Verwenden von Microsoft Entra ID zur Authentifizierung bei Azure Managed Redis.
- Python 3.10 oder höher.
- Die Azure CLI. Informationen zum Installieren finden Sie unter Installieren des Azure CLI.
Tip
Die vollständige, bereitstellungsfähige Version dieses Beispiels, einschließlich Infrastruktur als Code und alle vier Muster, finden Sie im Repository für amr-caching-pattern-samples auf GitHub.
Schritt 1: Installieren der Clientbibliotheken
Installieren Sie die Redis- und PostgreSQL-Clientbibliotheken zusammen mit der Azure Identitätsbibliothek für Microsoft Entra Authentifizierung.
pip install "redis>=5.0,<6.0" "psycopg[binary]>=3.1,<4.0" "azure-identity>=1.17,<2.0"
Schritt 2: Herstellen einer Verbindung mit Microsoft Entra ID
Verwenden Sie Microsoft Entra ID Authentifizierung anstelle von Zugriffstasten. Microsoft Entra ID entfernt die Notwendigkeit, geheime Schlüssel in Ihrer Anwendung zu speichern, und ermöglicht es Ihnen, den Zugriff zentral zu verwalten.
Der folgende Code erstellt einen Redis-Client und eine PostgreSQL-Verbindung, die beide über DefaultAzureCredential mit einer verwalteten Identität oder einer Entwickleranmeldeinformation authentifiziert werden. Im Beispiel wird der clusterfähige RedisCluster Client verwendet, der der osS-Clusteringrichtlinie entspricht, die in diesem Beispiel verwendet wird. Wenn Ihr Cache die Enterprise-Clustering-Richtlinie verwendet, verwenden Sie stattdessen den Standardclient redis.Redis .
import os
import json
import redis
from redis.cluster import RedisCluster
import psycopg
from azure.identity import DefaultAzureCredential
REDIS_HOST = os.environ["REDIS_HOST"] # for example, mycache.eastus.redis.azure.net
REDIS_PORT = 10000
PG_HOST = os.environ["PG_HOST"] # for example, myserver.postgres.database.azure.com
PG_DATABASE = os.environ["PG_DATABASE"]
credential = DefaultAzureCredential()
# Acquire a token for Azure Managed Redis and use it as the password.
redis_token = credential.get_token("https://redis.azure.com/.default")
# The username is the object ID of the Microsoft Entra identity.
redis_client = RedisCluster(
host=REDIS_HOST,
port=REDIS_PORT,
ssl=True,
ssl_check_hostname=False, # cluster nodes are reached by IP; the certificate chain is still validated
username=os.environ["REDIS_USER_OBJECT_ID"],
password=redis_token.token,
decode_responses=True,
)
# Acquire a token for Azure Database for PostgreSQL and use it as the password.
pg_token = credential.get_token("https://ossrdbms-aad.database.windows.net/.default")
pg_conn = psycopg.connect(
host=PG_HOST,
dbname=PG_DATABASE,
user=os.environ["PG_USER"],
password=pg_token.token,
sslmode="require",
)
Note
Microsoft Entra Zugriffstoken laufen in der Regel nach etwa einer Stunde ab. Aktualisieren Sie bei langlebigen Anwendungen das Token, bevor es abläuft, und verbinden Sie sich sowohl für Azure Managed Redis als auch für Azure Database for PostgreSQL erneut, oder verwenden Sie eine Hilfsfunktion, die Tokens transparent erneut abruft. Ausführliche Informationen finden Sie unter Verwenden von Microsoft Entra ID für die Authentifizierung mit Azure verwalteten Redis.
Schritt 3: Cache-aside
Cache-aside ist das gängigste Muster und wird in diesem Beispiel für Produktlesevorgänge verwendet. Die Anwendung überprüft zunächst Redis und fragt beim Fehlen PostgreSQL ab, wobei der Cache mit einer Time-to-Live (TTL) gefüllt wird. Einige beliebte Produkte fördern die meisten Lesevorgänge, sodass die Trefferrate hoch ist.
Da die meisten Lesevorgänge aus dem Speicher bereitgestellt werden, nimmt cache-aside die leselast von PostgreSQL nachhaltig ab. Diese Reduzierung bedeutet weniger Verbindungen, weniger Umschlag im Puffercache und eine geringere CPU-Auslastung sowie weniger IOPS. Sie können Lesespitzen auffangen, ohne den Server vertikal hochskalieren oder Repliken hinzufügen zu müssen. Sie fragen PostgreSQL nur bei einem Fehlen ab (beim ersten Zugriff oder nach Ablauf der TTL). Unter Was zwischengespeichert werden sollte finden Sie Informationen dazu, wie Sie die Abfragen ermitteln, die sich für das Zwischenspeichern eignen.
CACHE_TTL_SECONDS = 300 # 5 minutes
def get_product(product_id: int) -> dict | None:
cache_key = f"product:{product_id}"
# 1. Try the cache first.
cached = redis_client.get(cache_key)
if cached is not None:
return json.loads(cached)
# 2. On a miss, read from PostgreSQL.
with pg_conn.cursor() as cursor:
cursor.execute("SELECT id, name, price FROM products WHERE id = %s", (product_id,))
row = cursor.fetchone()
if row is None:
return None
product = {"id": row[0], "name": row[1], "price": float(row[2])}
# 3. Populate the cache with a TTL, then return.
redis_client.set(cache_key, json.dumps(product), ex=CACHE_TTL_SECONDS)
return product
Schritt 4: Prefetching von Referenzdaten
Statische Daten, die ständig gelesen werden, sich aber nur selten ändern (zum Beispiel Kategorien, Marken oder Versandkonfigurationen), müssen nicht auf einen Cache-Fehltreffer warten. Laden Sie sie im Voraus in den Cache, und aktualisieren Sie sie, wenn sich die Quelle ändert. In einem PostgreSQL-Schema sind dies in der Regel die kleinen Nachschlage- und Dimensionstabellen, die in viele Abfragen eingebunden werden. Wenn sie aus dem Arbeitsspeicher bedient werden, wird eine große Menge wiederholter Verknüpfungen und Nachschlagevorgänge aus der Datenbank entfernt. Im Gegensatz zu „Cache-aside“ gibt es keine Fehltreffer pro Anfrage und kein TTL-Race. Sie aktualisieren bei Änderungen, sodass Lesevorgänge stets „warm“ sind.
def prefetch_categories() -> None:
with pg_conn.cursor() as cursor:
cursor.execute("SELECT id, name FROM categories ORDER BY name")
categories = [{"id": r[0], "name": r[1]} for r in cursor.fetchall()]
redis_client.set("ref:categories", json.dumps(categories)) # no TTL; refreshed on change
def get_categories() -> list[dict]:
cached = redis_client.get("ref:categories")
return json.loads(cached) if cached else []
Schritt 5: Write-Through
Wenn eine Änderung sofort sichtbar sein muss, schreiben Sie PostgreSQL und den Cache in demselben Vorgang, anstatt darauf zu warten, dass eine TTL abläuft oder den Schlüssel ungültig macht. Dieses Muster wird beispielsweise zum Aktualisieren von Preisinformationen im Beispiel verwendet. PostgreSQL bleibt die Quelle der Wahrheit. Die Änderung wird zuerst dort ausgeführt, dann wird der Cache aktualisiert, sodass ein Lesevorgang nach dem Schreiben den neuen Wert zurückgibt.
Wenn in zwei Systeme geschrieben wird, die sich keine Transaktion teilen, kann der Datenbank-Commit erfolgreich sein, während die Cache-Aktualisierung fehlschlägt, und es gibt keine einfache Lösung. Der folgende Codeausschnitt zeigt den Idealfall und klammert die Fehlerbehandlung aus. In der Produktion entscheiden Sie, wie Sie mit einer fehlgeschlagenen Aktualisierung umgehen, z. B. indem Sie sie erneut versuchen, wenn der Fehler nur vorübergehend zu sein scheint, oder den Schlüssel invalidieren, sodass der nächste Lesevorgang die Daten erneut aus PostgreSQL lädt. Auf beiden Weise enthält PostgreSQL den richtigen Wert, sodass ein veralteter oder fehlender Cacheeintrag immer wiederhergestellt werden kann. Wenn die Aktualisierung des Caches zuverlässig erfolgen muss, sollte sie stattdessen durch den Änderungsstrom der Datenbank ausgelöst werden (siehe ereignisgesteuerte Invalidierung).
def update_price(product_id: int, new_price: float) -> None:
# 1. Write to PostgreSQL, the source of truth.
with pg_conn.cursor() as cursor:
cursor.execute("UPDATE products SET price = %s WHERE id = %s", (new_price, product_id))
pg_conn.commit()
# 2. Refresh the cached entry so reads see the new price right away.
with pg_conn.cursor() as cursor:
cursor.execute("SELECT id, name, price FROM products WHERE id = %s", (product_id,))
row = cursor.fetchone()
if row is not None:
product = {"id": row[0], "name": row[1], "price": float(row[2])}
redis_client.set(f"product:{product_id}", json.dumps(product), ex=CACHE_TTL_SECONDS)
Schritt 6: Ereignisgesteuerte Ungültigheit
Die ereignisgesteuerte Invalidierung hält den Cache konsistent mit der Datenbank, indem er auf Datenänderungsereignisse reagiert. Es aktualisiert Einträge oder macht sie ungültig, wenn sie sich ändern, anstatt sie per Timer ablaufen zu lassen. Autoren fügen Ereignisse an einen dauerhaften Redis-Stream an – ein Append-only-Protokoll –, und ein oder mehrere Consumer lesen diese Ereignisse und aktualisieren den Cache. Da der Stream persistent ist, bleiben Ereignisse auch bei einem Neustart des Consumers erhalten. Eine Verbrauchergruppe liefert jedes Ereignis an einen einzelnen Mitarbeiter, verfolgt Bestätigungen nach, sodass nichts zweimal verloren geht oder verarbeitet wird, und Sie können die Verarbeitung für mitarbeiterübergreifend skalieren.
Verwenden Sie dieses Muster, wenn ein zwischengespeicherter Wert von Daten abgeleitet wird, die sich an anderer Stelle ändern (Status, Projektion oder Aggregat), bei denen eine TTL entweder veraltete Daten bedient oder eine konstante Neuberechnung erzwingt. In der Storefront steuert dieses Muster den Bestellstatus durch den Fulfillment-Prozess. Beim Aufgeben einer Bestellung wird die Bestellung in PostgreSQL geschrieben, ihr Anfangsstatus zwischengespeichert und ein placed Ereignis an den Stream angehängt:
ORDER_STREAM = "orders:events"
def place_order(product_id: int, quantity: int) -> int:
with pg_conn.cursor() as cursor:
cursor.execute(
"INSERT INTO orders (product_id, quantity, status) VALUES (%s, %s, 'placed') RETURNING id",
(product_id, quantity),
)
order_id = cursor.fetchone()[0]
pg_conn.commit()
redis_client.set(f"order:{order_id}:status", "placed", ex=86400)
redis_client.xadd(ORDER_STREAM, {"order_id": order_id, "status": "placed"}, maxlen=10000, approximate=True)
return order_id
Ein Fulfillment-Worker führt eine Consumer-Gruppe aus: Er liest neue Ereignisse, schreitet bei jedem Auftrag in PostgreSQL voran, aktualisiert die zwischengespeicherte order:{id}:status-Projektion und bestätigt das Ereignis. Die Bestellseite liest diese Projektion, sodass Statusprüfungen schnell bleiben und die Datenbank nie berühren. Der Wert bleibt korrekt, weil Ereignisse ihn aktuell halten.
GROUP = "fulfillment"
def process_orders() -> None:
try:
redis_client.xgroup_create(ORDER_STREAM, GROUP, id="0", mkstream=True)
except redis.exceptions.ResponseError:
pass # group already exists
while True:
events = redis_client.xreadgroup(GROUP, "worker-1", {ORDER_STREAM: ">"}, count=10, block=5000)
for _stream, entries in events or []:
for event_id, fields in entries:
order_id = int(fields["order_id"])
with pg_conn.cursor() as cursor:
cursor.execute("UPDATE orders SET status = 'shipped' WHERE id = %s", (order_id,))
pg_conn.commit()
redis_client.set(f"order:{order_id}:status", "shipped", ex=86400)
redis_client.xack(ORDER_STREAM, GROUP, event_id)
Die Ereignisquelle in diesem Beispiel ist die Anwendung, die PostgreSQL schreibt und das Ereignis in demselben Pfad anfüge. PostgreSQL kann auch Änderungen selbst ausgeben: LISTEN/NOTIFY für einfache Benachrichtigungen oder logische Decodierung (Änderungsdatenerfassung) für einen dauerhaften Änderungsstrom auf Zeilenebene. Wenn der Cache über PostgreSQLs eigenen Änderungsstrom gesteuert wird, reagiert er auf jede bestätigte Änderung, selbst auf Schreibvorgänge, die an der Anwendung vorbeigehen.
Bewährte Methoden
Befolgen Sie diese Methoden, um Ihren Cache korrekt, effizient und kostengünstig zu halten.
- Legen Sie eine TTL fest, wo Veraltetheit ein Risiko ist. Eine TTL begrenzt die Veralterung, falls die Invalidierung fehlschlägt. Stimmen Sie die TTL mit der maximalen Veraltetkeit überein, die die Anwendung akzeptieren kann. Verwenden Sie eine lange TTL oder keine TTL nur für Referenzdaten, wenn zuverlässige Ungültigheits- und Aktualisierungsprozesse vorhanden sind.
- Verwenden Sie ein einheitliches Benennungsschema für Schlüssel. Vergeben Sie Namespace-Schlüssel nach Dienst, Entität und Kennung, wie z. B.
product:42oderuser:1001:profile. Fügen Sie eine Version hinzu, wenn sich das Schlüsselformat oder das Wertschema ändern kann. - Zwischenspeichern Sie die richtige Granularität. Zwischenspeichern Sie einzelne Entitäten oder kleine Ergebnismengen, wenn sie häufig wiederverwendet werden und sich leicht invalidieren lassen. Speichern Sie keine Daten zwischen, die nur wenig wiederverwendet werden. Übermäßiges Zwischenspeichern verschwendet Arbeitsspeicher und kann die Trefferrate verringern.
- Behandeln Sie Cache-Fehltreffer und Ausfälle elegant. Behandeln Sie den Cache als Optimierung, nicht als Quelle der Wahrheit. Wenn Redis nicht verfügbar ist, verwenden Sie einen gebundenen Fallback für PostgreSQL. Fügen Sie Timeouts, Schaltkreisbrecher, Backoff- und Anforderungsgrenzwerte hinzu, um PostgreSQL zu schützen. Wenn PostgreSQL kurzzeitig ausfällt, können Sie weiterhin Lesezugriffe für bereits im Cache gespeicherte Daten bedienen, während Schreibzugriffe warten müssen, bis die Datenbank sich erholt hat.
- Verhindern Sie Cache-Stampedes. Wenn ein häufig verwendeter Schlüssel abläuft, können viele Anfragen gleichzeitig auf die Datenbank treffen. Verwenden Sie TTL-Jitter, Request-Coalescing, „Stale-while-revalidate“ oder eine kurze verteilte Sperre, damit eine Anfrage den Eintrag neu befüllen kann.
- Passen Sie die Größe des Caches optimal an. Überwachen Sie die Trefferrate, die Speicherauslastung, die Verdrängungsrate, die Ablaufrate, die Latenz, häufig verwendete Schlüssel und die Schlüsselkardinalität. Eine niedrige Trefferrate kann auf einen Cache hinweisen, der zu klein ist, übermäßige Evictions, schlechte Schlüsselauswahl oder ein Muster mit schlechtem Zugriff. Anleitungen zur Größenanpassung finden Sie unter Azure Richtlinien für die Auswahl der verwalteten Redis-Ebene.
- Wählen Sie eine Verdrängungsrichtlinie aus, die zu Ihren Schlüsseln passt. Beginnen Sie bei einer reinen Cache-Datenbank mit allkeys-lru oder allkeys-lfu. Verwenden Sie eine veränderliche*-Richtlinie nur, wenn dieselbe Datenbank ablaufende Cacheschlüssel und geschützte nicht ablaufende Schlüssel enthält. Eine flüchtige Richtlinie kann die Entfernung stoppen, wenn keine Schlüssel eine TTL haben. Trennen Sie Cachedaten nach Möglichkeit von geschützten Daten.
- Serialisieren Sie effizient. JSON ist lesbar und portierbar. Testen Sie für Pfade mit hohem Durchsatz ein kompaktes Binärformat, um Arbeitsspeicher und Netzwerkaufwand zu reduzieren. Messen Sie Speichernutzung, CPU-Auslastung, Latenz, die Auswirkungen der Schema-Evolution und die Auswirkungen auf das Debugging, bevor Sie das Format ändern.
Suchen, was zwischengespeichert werden soll
Die effektivsten Cacheziele sind die Abfragen, die Ihre Anwendung am häufigsten für die Daten ausführt, die am wenigsten geändert werden. Anstatt zu erraten, welche Abfragen dieser Beschreibung entsprechen, vergleichen Sie die historischen und aktuellen Ansichten in der Abfragetelemetrie, die Azure Database for PostgreSQL sammeln können, wenn Sie die relevanten Features aktivieren:
- Abfragespeicher speichert Abfrageausführungsstatistiken für historische Analysen. Verwenden Sie Die Aufrufanzahl und die Gesamt- und mittlere Ausführungszeit, um Abfragen zu finden, die die Datenbankauslastung über längere Zeiträume konsistent beherrschen. Siehe "Überwachen der Leistung mit Abfragespeicher".
- Query Performance Insight visualisiert Abfragespeicher Daten im Azure-Portal, sodass Sie häufige und ressourcenintensive Abfragen erkennen und ihr Verhalten im Laufe der Zeit vergleichen können. Siehe Abfrageleistungserblick.
-
pg_stat_statementsstellt kumulative Statistiken pro Anweisung innerhalb der Datenbank bereit, um einen direkten Überblick über das aktuelle Beobachtungsfenster zu ermöglichen. Die Statistiken können zurückgesetzt werden. Verwenden Sie daher Abfragespeicher, wenn Sie den Verlauf über Beobachtungsfenster hinweg beibehalten müssen.
Verwenden Sie beide Ansichten, bevor Sie einen Cachekandidaten auswählen. Eine kurzfristige Spitze stellt möglicherweise nicht das normale Verhalten der Workload dar, während ein historischer Durchschnitt eine aktuelle Regression ausblenden kann. Priorisieren Sie Abfragen , die häufig, teuer und stabil sind, was eine hohe Anrufanzahl, eine hohe Gesamtausführungszeit und Ergebnisse bedeutet, die sich bei jeder Anforderung nicht ändern. Diese Abfragen liefern die höchste Cachetreffrate und den größten Rückgang der Datenbanklast. Eine Abfrage, die ständig ausgeführt wird, aber die gleichen Zeilen für Minuten zurückgibt, z. B. eine Produktauflistung, eine Kategoriestruktur oder eine Preistabelle, ist ein idealer Kandidat.