View a markdown version of this page

Ausführungsplan - Amazon Aurora

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Ausführungsplan

Aurora PostgreSQL lässt sich in die EXPLAIN-Infrastruktur von PostgreSQL integrieren, um Ihnen zu helfen, zu verstehen, wie Abfragen ausgeführt werden, Pushdown-Möglichkeiten zu identifizieren und Leistungsprobleme zu diagnostizieren. In diesem Thema wird erklärt, wie Ausführungspläne für Abfragen in Fremdtabellen gelesen werden, welche Plantypen es gibt und welche Faktoren die Planauswahl beeinflussen.

Plantypen

Aurora PostgreSQL verwendet zwei Pushdown-Strategien, die vom Planer automatisch ausgewählt werden:

Vollständiger Abfrage-Pushdown

Die gesamte Abfrage (einschließlich JOINs, Aggregationen, Unterabfragen, CTEs, ORDER BY und LIMIT) wird an die Analytics-Engine übertragen. Dies ist der schnellste Ausführungspfad.

Sie sehen einen einzelnen Custom Scan Knoten auf der obersten Ebene des Plans:

EXPLAIN (COSTS OFF) SELECT status, count(*), sum(total_amount) FROM ft_orders WHERE order_date > '2024-01-01' GROUP BY status ORDER BY sum(total_amount) DESC LIMIT 5;
QUERY PLAN -------------------------------------------- Custom Scan -> TOP_N Top: 5 Order By: sum(total_amount) DESC -> HASH_GROUP_BY Groups: #0 Aggregates: count_star(), sum(#1) -> READ_PARQUET Table: ft_orders Filters: order_date>'2024-01-01' Projections: status, total_amount

Alles, was sich darin Custom Scan befindet, wird von der Analytics-Engine mithilfe einer spaltenbasierten Verarbeitung ausgeführt.

Table-scan Pushdown (Fallback)

Wenn die vollständige Abfrage Konstrukte enthält, die nicht an die Analytical Engine übertragen werden können, greift Aurora PostgreSQL darauf zurück, nur den Fremdtabellenscan zu pushen. Beim Scan werden immer noch die unterstützten Filterbedingungen und Spaltenprojektionen heruntergesetzt, und die Engine liest nur die benötigten Spalten und Zeilen. Die JOINs-, Sortierungs- und nicht unterstützten Operationen werden dann in PostgreSQL ausgeführt.

Sie sehen Custom Scan Knoten, die in Standard-PostgreSQL-Knoten verschachtelt sind:

EXPLAIN (COSTS OFF) SELECT ft.price, soundex(ft.mainroad) FROM ft_house_price ft LIMIT 5;
QUERY PLAN -------------------------------------- Limit -> Custom Scan on ft_house_price -> READ_PARQUET Table: ft_house_price Projections: price, mainroad

Hier soundex() ist eine PostgreSQL-Funktion, die nicht an die Analyse-Engine übertragen werden kann. Die Engine liest die Spalten (price, mainroad) effizient über READ_PARQUET, dann wendet PostgreSQL lokal an. soundex()

Einen Ausführungsplan lesen: Komplettlösung

In den folgenden Beispielen werden reale Ausführungspläne aus einem TPC-H SF100-Datensatz (~34 GB Parquet) auf einer db.r8gd.8xlarge-Instance verwendet.

Beispiel 1: Vollständiger Abfrage-Pushdown (Aggregation mit Filter)

Dies ist TPC-H Abfrage 1, ein Scannen, Filtern, Gruppieren und Sortieren in einer einzigen großen Tabelle:

EXPLAIN (ANALYZE, VERBOSE, COSTS OFF, TIMING OFF, BUFFERS OFF, SUMMARY OFF) SELECT l_returnflag, l_linestatus, count(*), sum(l_quantity), avg(l_extendedprice) FROM ft_lineitem WHERE l_shipdate <= '1998-09-01' GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus;
Custom Scan (actual rows=4 loops=1) Output: aurora_analytics.l_returnflag, aurora_analytics.l_linestatus, aurora_analytics.count, ... Pushdown SQL: SELECT l_returnflag, l_linestatus, count(*) AS count, sum(l_quantity) AS sum, avg(l_extendedprice) AS avg FROM (SELECT l_quantity::DECIMAL(15,2) AS l_quantity, l_extendedprice::DECIMAL(15,2) AS l_extendedprice, l_returnflag::VARCHAR COLLATE "C" AS l_returnflag, l_linestatus::VARCHAR COLLATE "C" AS l_linestatus, l_shipdate::DATE AS l_shipdate FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_lineitem) ft_lineitem WHERE (l_shipdate <= '1998-09-01'::DATE) GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus -> ORDER_BY (actual rows=4 loops=1) Order By: ft_lineitem.l_returnflag ASC, ft_lineitem.l_linestatus ASC -> HASH_GROUP_BY (actual rows=4 loops=1) Groups: #0, #1 Aggregates: count_star(), sum(#2), avg(#3) -> PROJECTION (actual rows=591411581 loops=1) Projections: l_returnflag, l_linestatus, l_quantity, l_extendedprice -> READ_PARQUET (actual rows=591411581 loops=1) Table: ft_lineitem Filters: l_shipdate<='1998-09-01'::DATE Projections: l_quantity, l_extendedprice, l_returnflag, l_linestatus Total Files Read: 21 Rows Removed by Filter: 15303257125 Analytics Cache Hit Bytes: 4617440kB Analytics Remote Read Bytes: 16kB S3 HEAD Request Count: 0 S3 GET Request Count: 2

Lesen Sie diesen Plan von unten nach oben:

  1. READ_PARQUET: 21 ft_lineitem Parquet-Dateien durchsucht. Der Filter l_shipdate <= '1998-09-01' wurde auf die Scanebene verschoben (Prädikat Pushdown), wobei Zeilengruppen, die nicht übereinstimmten, übersprungen wurden. „Durch Filter entfernte Zeilen: 15.303.257.125“ bedeutet, dass Milliarden von Zeilengruppeneinträgen mithilfe von Statistiken entfernt wurden. min/max Es wurden nur 4 Spalten projiziert:,,,. l_quantity l_extendedprice l_returnflag l_linestatus Die anderen 12 Zeilenspalten wurden nie aus Amazon S3 gelesen.

  2. PROGNOSE: 591 Millionen qualifizierte Zeilen mit den 4 projizierten Spalten wurden an die Aggregationsphase übergeben.

  3. HASH_GROUP_BY: Gruppiert nach l_returnflag und l_linestatus (4 verschiedene Kombinationen), Berechnung, und. count(*) sum(l_quantity) avg(l_extendedprice) 591 Mio. Zeilen wurden auf 4 Ausgabezeilen reduziert.

  4. ORDER_BY: Die 4 Ergebniszeilen wurden nach, sortiert. l_returnflag l_linestatus

  5. Benutzerdefinierter Scan (aurora_analytics): Wrapper. Top-level Hat 4 Zeilen an PostgreSQL zurückgegeben. Die Pushdown SQL Zeile bestätigt, dass die gesamte Abfrage an die Analyse-Engine weitergeleitet wurde.

Cache- und S3-Metriken:

  • Cache-Treffer: ~4,5 GB (warm, Daten wurden aus früheren Läufen zwischengespeichert)

  • Fernlesen: 16 KB (fast alles wurde aus dem Cache bedient)

  • 0 HEAD-Anfragen, 2 GET-Anfragen (minimale Amazon S3 S3-Aktivität)

  • Fast alle Daten wurden mit minimaler Amazon S3 S3-Aktivität aus dem Cache bereitgestellt

Beispiel 2: Multi-table JOIN mit vollständigem Pushdown

Dies ist TPC-H Query 5, ein Join mit 4 Tabellen mit Filter, Aggregation, Sortierung und Limit:

EXPLAIN (ANALYZE, VERBOSE, COSTS OFF, TIMING OFF, BUFFERS OFF, SUMMARY OFF) SELECT n_name, count(*), sum(l_extendedprice * (1 - l_discount)) as revenue FROM ft_lineitem JOIN ft_orders ON l_orderkey = o_orderkey JOIN ft_customer ON o_custkey = c_custkey JOIN ft_nation ON c_nationkey = n_nationkey WHERE o_orderdate >= '1994-01-01' AND o_orderdate < '1995-01-01' GROUP BY n_name ORDER BY revenue DESC LIMIT 5;
Custom Scan (actual rows=5 loops=1) Output: aurora_analytics.n_name, aurora_analytics.count, (aurora_analytics.revenue)::numeric Pushdown SQL: SELECT ft_nation.n_name, count(*) AS count, sum((ft_lineitem.l_extendedprice * ((1::INTEGER)::numeric - ft_lineitem.l_discount))) AS revenue FROM ((((SELECT ... FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_lineitem) ... JOIN ... ft_orders ... JOIN ... ft_customer ... JOIN ... ft_nation ...))) WHERE ((ft_orders.o_orderdate >= '1994-01-01'::DATE) AND (ft_orders.o_orderdate < '1995-01-01'::DATE)) GROUP BY ft_nation.n_name ORDER BY ... DESC LIMIT 5::INTEGER -> TOP_N (actual rows=5 loops=1) Top: 5 Order By: sum(...) DESC -> HASH_GROUP_BY (actual rows=25 loops=1) Groups: #0 Aggregates: count_star(), sum(#1) -> PROJECTION (actual rows=91044214 loops=1) Projections: n_name, (l_extendedprice * (1.000 - CAST(l_discount AS DECIMAL(18,3)))) -> HASH_JOIN (actual rows=91044214 loops=1) Join Type: INNER Conditions: l_orderkey = o_orderkey -> READ_PARQUET (actual rows=92006243 loops=1) Table: ft_lineitem Projections: l_orderkey, l_extendedprice, l_discount Dynamic Filters: optional: l_orderkey>=5 AND l_orderkey<=599999975 AND l_orderkey IN BF(o_orderkey) Total Files Read: 21 Rows Removed by Filter: 15802662463 -> HASH_JOIN (actual rows=22760819 loops=1) Join Type: INNER Conditions: c_custkey = o_custkey -> HASH_JOIN (actual rows=10099742 loops=1) Join Type: INNER Conditions: c_nationkey = n_nationkey -> READ_PARQUET (actual rows=10099742 loops=1) Table: ft_customer Projections: c_custkey, c_nationkey Dynamic Filters: optional: c_custkey>=1 AND c_custkey<=14999999 AND c_custkey IN BF(o_custkey) Total Files Read: 2 Rows Removed by Filter: 856257246 -> READ_PARQUET (actual rows=25 loops=1) Table: ft_nation Projections: n_nationkey, n_name Total Files Read: 1 -> READ_PARQUET (actual rows=22760819 loops=1) Table: ft_orders Filters: o_orderdate>='1994-01-01'::DATE AND o_orderdate<'1995-01-01'::DATE Projections: o_orderkey, o_custkey Total Files Read: 6 Rows Removed by Filter: 4526635795 Analytics Cache Hit Bytes: 3330521kB Analytics Remote Read Bytes: 2514317kB S3 HEAD Request Count: 0 S3 GET Request Count: 4922

Lesen Sie diesen Plan von unten nach oben:

  1. Vier READ_PARQUET-Knoten: Jede Fremdtabelle wird unabhängig gescannt:

    • ft_nation: 25 Zeilen aus einer Datei (Tabelle mit kleinen Dimensionen)

    • ft_customer: 10 Millionen Zeilen aus 2 Dateien, mit dynamischer Filterung beim Zusammenführen der Bestellungen

    • ft_orders: 22,8 Millionen Zeilen aus 6 Dateien, nach der Filterung bis zum Jahr 1994 (4,5 Milliarden Zeilen wurden durch den Datumsfilter entfernt)

    • ft_lineitem: 92 Millionen Zeilen aus 21 Dateien, wobei der Bloom-Filter über den Join-Key für Bestellungen gedrückt wird

  2. Drei HASH_JOIN-Knoten: Die Engine erstellt Hash-Tabellen und verknüpft sie der Reihe nach:

    • Nation Kunde (ein) c_nationkey = n_nationkey

    • Ergebnis Bestellungen (eino_custkey = c_custkey)

    • Ergebnis Lineitem (ein) l_orderkey = o_orderkey

  3. Dynamische Filter: Aurora PostgreSQL übergibt Join-Schlüsselbereiche und Bloom-Filter von der Build-Seite an den Scan der Testseite. Das l_orderkey IN BF(o_orderkey) bedeutet, dass nur Zeilenzeilen gelesen werden, die den Ordnungsschlüsseln entsprechen, was eine signifikante Optimierung darstellt.

  4. PROJEKTION: Berechnet 91 Millionen l_extendedprice * (1 - l_discount) verbundene Zeilen.

  5. HASH_GROUP_BY: Gruppiert nach n_name (25 Nationen), reduziert 91 Millionen Zeilen auf 25 Gruppen.

  6. TOP_N: Führt die Top 5 nach absteigendem Umsatz an.

Cache- und S3-Metriken:

  • Cache-Treffer: ~3,3 GB

  • Fernlesen: ~2,5 GB (teilweise Cache-Abdeckung, einige Daten sind noch kalt)

  • 4.922 S3 GET-Anfragen in 4 Tabellen (insgesamt 30 Dateien)

  • Der vollständige Abfrage-Pushdown wurde bestätigt: Alle 4 Tabellen wurden innerhalb der Analyse-Engine zusammengeführt

Beispiel 3: Vollständiger Abfrage-Pushdown mit einer lokalen Tabelle

Eine hybride Abfrage, die eine Fremdtabelle mit einer lokalen PostgreSQL-Tabelle (Heap) verknüpft, kann vollständig nach unten verschoben werden: Die Analytics-Engine liest die lokale Tabelle und führt die Verknüpfung und Aggregation selbst durch, sofern die Abfrage nur unterstützte Funktionen, Datentypen und Sortierungen verwendet. Im folgenden Beispiel local_supp wird eine lokale Heap-Tabelle über Integer-Schlüssel mit der ft_lineitem Fremdtabelle verknüpft:

EXPLAIN (VERBOSE, COSTS OFF) SELECT ls.s_regionkey, count(*) FROM ft_lineitem JOIN local_supp ls ON ft_lineitem.l_suppkey = ls.s_suppkey WHERE l_shipdate > '1998-01-01' GROUP BY ls.s_regionkey;
Custom Scan Output: aurora_analytics.s_regionkey, aurora_analytics.count Pushdown SQL: SELECT ls.s_regionkey, count(*) AS count FROM ((SELECT l_suppkey::BIGINT AS l_suppkey, l_shipdate::DATE AS l_shipdate FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_lineitem) ft_lineitem JOIN aurora_analytics.public.local_supp ls ON ((ft_lineitem.l_suppkey = ls.s_suppkey))) WHERE (ft_lineitem.l_shipdate > '1998-01-01'::DATE) GROUP BY ls.s_regionkey -> HASH_GROUP_BY Groups: #0 Aggregates: count_star() -> PROJECTION Projections: s_regionkey -> HASH_JOIN Join Type: INNER Conditions: l_suppkey = CAST(s_suppkey AS BIGINT) -> READ_PARQUET Table: ft_lineitem Filters: l_shipdate>'1998-01-01'::DATE Projections: l_suppkey -> POSTGRES_SCAN Table: local_supp Projections: s_suppkey, s_regionkey

Ich lese diesen Plan:

  1. Einzelner benutzerdefinierter Scan auf oberster Ebene: Die gesamte Abfrage, einschließlich der Verknüpfung mit der lokalen Tabelle, wird per Push an die Analytics-Engine übertragen. Im Gegensatz zum obigen Tablescan-Pushdown-Fall gibt es keine PostgreSQL-Knoten (HashAggregate, Hash Join), die es umschließen.

  2. POSTGRES_SCAN (local_supp): Die lokale Heap-Tabelle wird von der Analytics-Engine selbst gelesen und in die Push-Down-Tabelle eingespeist. HASH_JOIN Die lokale Tabelle nimmt an der Verknüpfung innerhalb der Engine teil, anstatt später von PostgreSQL verknüpft zu werden.

  3. READ_PARQUET (ft_lineitem): Beim Scannen fremder Tabellen werden nur der Filter und die Projekte übertragen. l_shipdate l_suppkey

  4. HASH_JOIN, HASH_GROUP_BY: Der Join und die /-Aggregation laufen beide innerhalb der Engine. GROUP BY count(*)

Wichtiger Hinweis: Das Verbinden einer fremden Tabelle mit einer lokalen Tabelle erzwingt keinen Fallback. Solange jede Funktion, jeder Datentyp und jede Sortierung in der Abfrage unterstützt werden, wird die lokale Tabelle in die Analytics-Engine übertragen und die gesamte Abfrage wird nach unten übertragen.

Das Verbinden einer fremden Tabelle mit einer lokalen PostgreSQL-Tabelle allein verhindert nicht den vollständigen Pushdown. Die Analyse-Engine kann eine lokale Tabelle in einen Push-Down-Join ziehen. Ein vollständiger Pushdown wird nur verhindert, wenn die Abfrage auf etwas verweist, das die Engine nicht herunterdrücken kann, z. B. eine Funktion, ein Datentyp oder eine Sortierung, die nicht unterstützt wird. Im folgenden Beispiel hat die Spalte n_name der Tabelle Local Nation den Wert character (25), einen nicht unterstützten Typ, sodass Aurora PostgreSQL nur den Fremdtabellenscan pusht und den Join in PostgreSQL durchführt:

EXPLAIN (VERBOSE, COSTS OFF) SELECT n_name, count(*) FROM ft_lineitem JOIN nation ON ft_lineitem.l_suppkey = nation.n_nationkey WHERE l_shipdate > '1998-01-01' GROUP BY n_name;
HashAggregate Output: nation.n_name, count(*) Group Key: nation.n_name -> Hash Join Output: nation.n_name Hash Cond: (l_suppkey = nation.n_nationkey) -> Custom Scan on public.ft_lineitem Output: l_orderkey, l_partkey, l_suppkey, ... Pushdown SQL: SELECT l_suppkey FROM (SELECT l_suppkey::BIGINT AS l_suppkey, l_shipdate::DATE AS l_shipdate FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_lineitem) ft_lineitem WHERE (l_shipdate > '1998-01-01'::DATE) -> READ_PARQUET Table: ft_lineitem Filters: l_shipdate>'1998-01-01'::DATE Projections: l_suppkey -> Hash Output: nation.n_name, nation.n_nationkey -> Seq Scan on public.nation Output: nation.n_name, nation.n_nationkey Unsupported Pushdown Expressions: 1: Type Description: character(25)

Ich lese diesen Plan:

  1. Planstruktur: Im Gegensatz zu den vorherigen Beispielen enthält dieser Plan PostgreSQL-Knoten (HashAggregate, Hash Join, Seq Scan), die den benutzerdefinierten Scan der Analyse-Engine einschließen. Dabei handelt es sich um einen Pushdown beim Tabellenscan, nicht um einen vollständigen Abfrage-Pushdown.

  2. Benutzerdefinierter Scan (ft_lineitem): Aurora PostgreSQL verarbeitet nur den Fremdtabellenscan. Es überträgt nur l_suppkey den l_shipdate > '1998-01-01' Filter und projiziert, ein effizienter Spaltenscan mit Prädikats-Pushdown.

  3. Seq Scan (Nation): Die lokale nation Tabelle wird über den Standard-Executor von PostgreSQL gelesen (shared_buffers → Aurora Storage).

  4. Hash Join: PostgreSQL verbindet die beiden Ergebnismengen mithilfe eines Hash-Joins on. l_suppkey = n_nationkey

  5. HashAggregate: PostgreSQL führt die Aggregation GROUP BY und count (*) durch.

  6. Nicht unterstützte Pushdown-Ausdrücke: Der Grund, warum der vollständige Pushdown fehlgeschlagen ist: character(25) (der n_name Spaltentyp in der lokalen Tabelle). nation Der char(n) Typ wird für Pushdown nicht unterstützt. Wenn es sich bei dieser Tabelle um eine Fremdtabelle mit TEXT Spalten handeln würde, wäre ein vollständiger Pushdown erfolgreich.

Wichtiger Hinweis: Beim Pushdown von Tabellenscans bietet Aurora PostgreSQL immer noch einen Mehrwert durch effizientes spaltenorientiertes Scannen mit Prädikat-Pushdown und Spaltenbereinigung. PostgreSQL verarbeitet nur die Operationen, die nicht nach unten verschoben werden können (nicht unterstützte Funktionen, Datentypen oder Sortierungen). Hätte die lokale Tabelle einen unterstützten Typ verwendet, z. B. text mit einer kompatiblen Sortierung, wäre der gesamte Hybrid-Join als einziger benutzerdefinierter Scan an die Analytics-Engine weitergeleitet worden.

Verwenden Sie EXPLAIN VERBOSE, um Pushdown-SQL zu sehen

EXPLAIN VERBOSEenthüllt das genaue SQL, das an die Analyse-Engine gesendet wurde:

EXPLAIN (VERBOSE, COSTS OFF) SELECT status, count(*), avg(total_amount) FROM ft_orders WHERE order_date > '2024-01-01' GROUP BY status;
QUERY PLAN ------------------------------------------------------------------------ Custom Scan Output: aurora_analytics.status, aurora_analytics.count, aurora_analytics.avg Pushdown SQL: SELECT status, count(*) AS count, avg(total_amount) AS avg FROM (SELECT status::VARCHAR COLLATE "C" AS status, total_amount::DECIMAL(12,2) AS total_amount, order_date::TIMESTAMP AS order_date FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_orders) ft_orders WHERE (order_date > '2024-01-01'::TIMESTAMP) GROUP BY status -> HASH_GROUP_BY Groups: #0 Aggregates: count_star(), avg(#1) -> READ_PARQUET Table: ft_orders Filters: order_date>'2024-01-01' Projections: status, total_amount, order_date

Die Pushdown SQL Zeile zeigt:

  • Wie PostgreSQL-Typen in die Typen der Analytical Engine umgewandelt werden (zum Beispiel) status::VARCHAR COLLATE "C"

  • Die parametrisierte Dateireferenz () $aurora_analytics_parameter_1

  • Die exakten Werte WHERE, GROUP BY und Aggregationen werden an die Engine übertragen

Grundlegendes zu „Nicht unterstützten Pushdown-Ausdrücken“

Wenn der vollständige Abfrage-Pushdown fehlschlägt, wird im EXPLAIN VERBOSE Abschnitt „Nicht unterstützte Pushdown-Ausdrücke“ angegeben, warum. Hier erfahren Sie, welche Konstrukte den Fallback zum Pushdown beim Tabellenscan erzwungen haben:

EXPLAIN (VERBOSE, COSTS OFF) SELECT soundex(name), age FROM ft_passengers LIMIT 5;
QUERY PLAN ------------------------------------------------------------------------ Limit Output: (soundex(name)), age -> Custom Scan on public.ft_passengers Output: soundex(name), age Pushdown SQL: SELECT name, age FROM (SELECT name::VARCHAR COLLATE "C" AS name, age::DOUBLE AS age FROM system.main.read_parquet($aurora_analytics_parameter_1) AS ft_passengers) ft_passengers -> READ_PARQUET Table: ft_passengers Projections: name, age Unsupported Pushdown Expressions: 1: Function Description: soundex(text)

Der Plan zeigt:

  • PostgreSQL verarbeitet den Funktionsaufruf Limit und soundex()

  • Aurora PostgreSQL verarbeitet nur den Tabellenscan (Lesen name und age Spalten)

  • Grund: soundex(text) ist keine Pushdown-sichere Funktion

Kategorien von Ausdrücken, die nicht unterstützt werden

Kategorie Beispiele Problemlösung
Funktion soundex(text),st_makepoint(...), uuid_generate_v4() UDFs Schreiben Sie ohne die Funktion neu oder akzeptieren Sie den Tabellenscan-Pushdown
Typ vector, Besetzungen, bytea integer[] geometry Verwenden Sie unterstützte Typen in Ausdrücken
Operator ~(Regex), LIKE mit Kollatierung außerhalb von C, (pgvector) <+> Verwenden Sie C-Kollation oder Pushdown-sichere Operatoren
Kollation Non-C Sortierung von Vergleichsausdrücken Explizit verwenden COLLATE "C"
Aggregate percent_rank(), array_agg() Schreiben Sie mit unterstützten Aggregaten um
SQL-Syntax ONLYSchlüsselwort, leere Zielliste, rekursive CTEs, dynamische Datenmaskierung Strukturieren Sie die Abfrage neu

Abfragen für den vollständigen Pushdown optimieren

Um die Leistung zu maximieren, sollten Sie einen vollständigen Abfrage-Pushdown anstreben. Verwenden Sie diese EXPLAIN VERBOSE Option, um Ihre Abfragen zu überprüfen und nicht unterstützte Ausdrücke zu korrigieren:

Schritt 1: Überprüfen Sie Ihre Abfrage

EXPLAIN (VERBOSE, COSTS OFF) SELECT ... FROM ft_table ...;

Suchen Sie in der Ausgabe nach „Nicht unterstützte Pushdown-Ausdrücke“.

Schritt 2: Identifizieren Sie die Ursache

Falls vorhanden, lesen Sie die Kategorie und die Beschreibung, um zu verstehen, was den vollständigen Pushdown verhindert hat.

Schritt 3: Korrigieren Sie den Ausdruck

  • Nicht unterstützte Funktion: Es gibt kein Rewrite, das eine nicht unterstützte Funktion herunterdrückt. Wenn eine Abfrage eine nicht unterstützte Funktion (z. B.soundex()) auf eine fremde Tabellenspalte anwendet, greift Aurora PostgreSQL automatisch auf den Tabellenscan-Pushdown zurück: Es überträgt den Scan, die Projektion und alle unterstützten Filter weiterhin an die Analyse-Engine und wendet die Funktion in PostgreSQL auf die zurückgegebenen Zeilen an. Um den vollen Pushdown wiederherzustellen, vermeiden Sie die nicht unterstützte Funktion bei Abfragen von Fremdtabellen oder berechnen Sie das Ergebnis vorab in den Quelldaten. Andernfalls akzeptieren Sie den Pushdown für den Tabellenscan, wodurch Sie trotzdem effizient in Spalten scannen können.

  • Non-C Sortierung: Fügen Sie explizite Textvergleiche hinzu: COLLATE "C"

    -- Instead of: WHERE name LIKE 'Smith%' -- Use: WHERE name COLLATE "C" LIKE 'Smith%'
  • Nicht unterstützter Typ: Vermeiden Sie die Umwandlung in nicht unterstützte Typen in Ausdrücken für fremde Tabellenspalten.

Schritt 4: Überprüfen

Führen Sie nach dem Reparieren erneut aus EXPLAIN VERBOSE und stellen Sie sicher, dass „Unsupported Pushdown Expressions“ nicht mehr verfügbar ist.

EXPLAIN ANALYZE-Metrik-Referenz

Bei Verwendung EXPLAIN ANALYZE werden die folgenden analysespezifischen Metriken am Ende der EXPLAIN Ausgabe angezeigt, die Amazon S3- und Cache-Aktivitäten für die gesamte Abfrage zusammenfassen. Jedes hat eine entsprechende instanzweite CloudWatch Amazon-Metrik, die Sie für Dashboards und Alarme abfrageübergreifend verwenden können:

Metrik Description Verwandte Metrik
Analytics Cache Hit Bytes Daten, die aus dem lokalen Festplatten-Cache bereitgestellt werden AuroraAnalyticsCacheHit(Amazon CloudWatch, instanzweit)
Analytics Remote Read Bytes Von Amazon S3 abgerufene Daten (Cache-Fehler) AuroraAnalyticsRemoteRead(Amazon CloudWatch, instanzweit)
S3 HEAD Request Count Anzahl der S3 HEAD-Anfragen (Metadatenprüfungen) AuroraAnalyticsS3HeadRequest(Amazon CloudWatch, instanzweit)
S3 GET Request Count Anzahl der S3 GET-Anfragen (Datenabrufe) AuroraAnalyticsS3GetRequest(Amazon CloudWatch, instanzweit)

Wenn aurora_analytics.track_detailed_metrics aktiviert, meldet jeder Custom Scan Knoten auch die folgenden Ausführungsmetriken pro Knoten:

Metrik Description Verwandte Metrik
Total CPU Time CPU-Zeit, die die Analytics-Engine während der Ausführung dieses Knotens aufgewendet hat siehe analytics_total_cpu_time in aurora_analytics_stat_statements()
Effective Parallelism Durchschnittliche Anzahl aktiver Worker-Threads während der Ausführung dieses Knotens AuroraAnalyticsActiveThreads(Amazon CloudWatch, instanzweit)
Total Thread Wait Time Wartezeit der Worker-Threads der Engine während der Ausführung dieses Knotens siehe analytics_total_thread_wait_time in aurora_analytics_stat_statements()

Tipps für die Analyse des Ausführungsplans

  • Immer EXPLAIN VERBOSE beim Debuggen von Pushdown-Verhalten verwenden. Es zeigt sowohl als auchPushdown SQL. Unsupported Pushdown Expressions

  • Ein einziger Custom Scan Eintrag auf der obersten Ebene des Plans = vollständiger Pushdown (am schnellsten). Ein Custom Scan verschachtelter innerer PostgreSQL-Knoten (egal ob einer oder mehrere) = Table-Scan-Pushdown (langsamer, nutzt aber immer noch den Spaltenscan).

  • Die folgende Filters Zeile READ_PARQUET bestätigt, dass Ihre WHERE-Klausel auf die Scanebene übertragen wurde. Wenn Sie stattdessen Filter: auf der Custom Scan Ebene sehen, wurde das Prädikat nicht ganz nach unten verschoben.

  • Projectionsunten READ_PARQUET zeigt, welche Spalten aus Parquet gelesen wurden. Eine Abfrage, die weniger Spalten projiziert, liest weniger Daten. Vermeiden SELECT * Sie fremde Tabellen.

  • Total Files Readgibt an, wie viele Parquet-Dateien gescannt wurden. Wenn dieser Wert hoch erscheint, sollten Sie eine Partitionierung Ihrer Daten in Betracht ziehen.

  • Rows Removed by Filterzeigt die Effektivität von Pushdown anhand von Prädikaten. Hohe Werte bedeuten, dass der Filter auf Scanebene einwandfrei funktioniert.