Single-Shard-Abfragen in Aurora PostgreSQL Limitless Database - 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.

Single-Shard-Abfragen in Aurora PostgreSQL Limitless Database

Eine Single-Shard-Abfrage ist eine Abfrage, die direkt auf einem Shard ausgeführt werden kann, wobei die SQL ACID-Semantik beibehalten wird. Wenn der Abfrageplaner auf dem Router auf eine solche Abfrage trifft, erkennt der Planer sie und fährt fort, die gesamte SQL-Abfrage an den entsprechenden Shard weiterzuleiten.

Diese Optimierung reduziert die Anzahl der Netzwerk-Roundtrips vom Router zum Shard und verbessert so die Leistung. Derzeit wird diese Optimierung fürINSERT, SELECTUPDATE, und DELETE Abfragen durchgeführt.

Beispiele für Single-Shard-Abfragen

In den folgenden Beispielen haben wir die Sharded-Tabelle customers mit dem Shard-Schlüssel customer_id und die Referenztabelle. zipcodes

SELECT
postgres_limitless=> EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM customers WHERE customer_id = 100; QUERY PLAN --------------------------------------------------------- Foreign Scan Output: customer_id, other_id, customer_name, balance Remote SQL: SELECT customer_id, other_id, customer_name, balance FROM public.customers WHERE (customer_id = 100) Single Shard Optimized (9 rows)
postgres_limitless=> EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM orders LEFT JOIN zipcodes ON orders.zipcode_id = zipcodes.zipcode_id WHERE customer_id = 11; QUERY PLAN --------------------------------------------------------------------------------------------------------- Foreign Scan Output: customer_id, order_id, zipcode_id, customer_name, balance, zipcodes.zipcode_id, zipcodes.city Remote SQL: SELECT orders.customer_id, orders.order_id, orders.zipcode_id, orders.customer_name, orders.balance, zipcodes.zipcode_id, zipcodes.city FROM (public.orders LEFT JOIN public.zipcodes ON ((orders.zipcode_id = zipcodes.zipcode_id))) WHERE (orders.customer_id = 11) Single Shard Optimized (13 rows)
INSERT
postgres_limitless=> EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO customers (customer_id, other_id, customer_name, balance) VALUES (1, 10, 'saikiran', 1000); QUERY PLAN ------------------------------------------------------- Insert on public.customers -> Result Output: 1, 10, 'saikiran'::text, '1000'::real Single Shard Optimized (4 rows)
AKTUALISIERUNG
postgres_limitless=> EXPLAIN (VERBOSE, COSTS OFF) UPDATE orders SET balance = balance + 100 WHERE customer_id = 100; QUERY PLAN --------------------------------------------------------------------------------------------- Update on public.orders Foreign Update on public.orders_fs00002 orders_1 -> Foreign Update Remote SQL: UPDATE public.orders SET balance = (balance + (100)::double precision) WHERE (customer_id = 100) Single Shard Optimized (6 rows)
DELETE
postgres_limitless=> EXPLAIN (VERBOSE, COSTS OFF) DELETE FROM orders WHERE customer_id = 100 and balance = 0; QUERY PLAN --------------------------------------------------------------------- Delete on public.orders Foreign Delete on public.orders_fs00002 orders_1 -> Foreign Delete Remote SQL: DELETE FROM public.orders WHERE ((customer_id = 100) AND (balance = (0)::double precision)) Single Shard Optimized (6 rows)

Einschränkungen für Single-Shard-Abfragen

Für Single-Shard-Abfragen gelten die folgenden Einschränkungen:

Funktionen

Wenn eine Single-Shard-Abfrage eine Funktion enthält, kommt die Abfrage nur dann für die Single-Shard-Optimierung in Frage, wenn eine der folgenden Bedingungen zutrifft:

  • Die Funktion ist unveränderlich. Weitere Informationen finden Sie unter Funktion: Volatilität.

  • Die Funktion ist veränderbar, aber in der rds_aurora.limitless_distributed_functions Ansicht registriert. Weitere Informationen finden Sie unter Verteilung der Funktionen.

Ansichten

Wenn eine Abfrage eine oder mehrere Ansichten enthält, ist die Single-Shard-Optimierung für die Abfrage deaktiviert, wenn sie eine der folgenden Bedingungen erfüllt:

  • Jede Ansicht hat das security_barrier Attribut.

  • Für die in der Abfrage verwendete Objekte sind mehrere Benutzerrechte erforderlich. Eine Abfrage enthält beispielsweise zwei Ansichten, und die Ansichten werden unter zwei verschiedenen Benutzern ausgeführt.

CREATE VIEW v1 AS SELECT customer_name FROM customers c WHERE c.customer_id = 1; CREATE VIEW v2 WITH (security_barrier) AS SELECT customer_name FROM customers c WHERE c.customer_id = 1; postgres_limitless=> EXPLAIN VERBOSE SELECT * FROM v1; QUERY PLAN ------------------------------------------------------------------------------------ Foreign Scan (cost=100.00..101.00 rows=100 width=0) Output: customer_name Remote Plans from Shard postgres_s3: Seq Scan on public.customers_ts00001 c (cost=0.00..24.12 rows=6 width=32) Output: c.customer_name Filter: (c.customer_id = 1) Query Identifier: -6005737533846718506 Remote SQL: SELECT customer_name FROM ( SELECT c.customer_name FROM public.customers c WHERE (c.customer_id = 1)) v1 Query Identifier: -5754424854414896228 (12 rows) postgres_limitless=> EXPLAIN VERBOSE SELECT * FROM v2; QUERY PLAN -------------------------------------------------------------------------------------------- Foreign Scan on public.customers_fs00001 c (cost=100.00..128.41 rows=7 width=32) Output: c.customer_name Remote Plans from Shard postgres_s3: Seq Scan on public.customers_ts00001 customers (cost=0.00..24.12 rows=6 width=32) Output: customers.customer_name Filter: (customers.customer_id = 1) Query Identifier: 4136563775490008117 Remote SQL: SELECT customer_name FROM public.customers WHERE ((customer_id = 1)) Query Identifier: 5056054318010163757 (9 rows)
Anweisungen PREPARE und EXECUTE

Aurora PostgreSQL Limitless Database unterstützt die Single-Shard-Optimierung für vorbereiteteSELECT, und Anweisungen. UPDATE DELETE

Wenn Sie jedoch vorbereitete Anweisungen für PREPARE und EXECUTE mit der plan_cache_mode Einstellung auf verwenden'force_generic_plan', lehnt der Abfrageplaner die Single-Shard-Optimierung für diese Abfrage ab.

PL/pgSQL

Abfragen mit PL/pgSQL variables are run as implicitly prepared statements. If a query contains any PL/pgSQL Variablen lehnt der Abfrageplaner die Single-Shard-Optimierung ab.

Die Optimierung wird in den Variablen unterstützt. PL/pgSQL block if the statement doesn't contain any PL/pgSQL

Vollständig qualifizierte (explizite) Verknüpfungen

Die Single-Shard-Optimierung basiert auf der Eliminierung von Partitionen. Der PostgreSQL-Optimierer entfernt Partitionen auf der Grundlage konstanter Bedingungen. Wenn Aurora PostgreSQL Limitless Database feststellt, dass sich alle verbleibenden Partitionen und Tabellen auf demselben Shard befinden, markiert sie die Abfrage, die für die Single-Shard-Optimierung in Frage kommt. Alle Filterbedingungen müssen explizit sein, damit das Eliminieren von Partitionen funktioniert. Aurora PostgreSQL Limitless Database kann Partitionen ohne ein oder mehrere Join-Prädikate oder Filterprädikate für die Shard-Schlüssel jeder fragtierten Tabelle in der Anweisung nicht löschen.

Gehen Sie davon aus, dass wir die Tabellen, und auf der Grundlage der Spalte partitioniert haben. customers orders order_details customer_id In diesem Schema versucht die Anwendung, alle Daten für einen Kunden auf einem einzigen Shard zu speichern.

Betrachten Sie folgende Abfrage:

SELECT * FROM customers c, orders o, order_details od WHERE c.customer_id = o.customer_id AND od.order_id = o.order_id AND c.customer_id = 1;

Diese Abfrage ruft alle Daten für einen Kunden ab ()c.customer_id = 1. Die Daten für diesen Kunden befinden sich auf einem einzigen Shard, aber Aurora PostgreSQL Limitless Database qualifiziert diese Abfrage nicht als Single-Shard-Abfrage. Der Optimierungsprozess für die Abfrage sieht wie folgt aus:

  1. Der Optimierer kann Partitionen für customers und auf der orders Grundlage der folgenden Bedingung entfernen:

    c.customer_id = 1 c.customer_id = o.customer_id o.customer_id = 1 (transitive implicit condition)
  2. Der Optimierer kann keine Partitionen für entfernenorder_details, da es in der Tabelle keine konstante Bedingung gibt.

  3. Der Optimierer kommt zu dem Schluss, dass er alle Partitionen von gelesen hat. order_details Daher kann die Abfrage nicht für die Single-Shard-Optimierung qualifiziert werden.

Um dies zu einer Single-Shard-Abfrage zu machen, fügen wir die folgende explizite Join-Bedingung hinzu:

o.customer_id = od.customer_id

Die geänderte Abfrage sieht wie folgt aus:

SELECT * FROM customers c, orders o, order_details od WHERE c.customer_id = o.customer_id AND o.customer_id = od.customer_id AND od. order_id = o. order_id AND c.customer_id = 1;

Jetzt kann der Optimierer Partitionen für order_details eliminieren. Die neue Abfrage wird zu einer Single-Shard-Abfrage und ist für die Optimierung geeignet.

Einen aktiven Shard-Schlüssel festlegen

Mit dieser Funktion können Sie bei der Datenbankabfrage einen einzelnen Shard-Schlüssel festlegen, sodass an alle Abfragen SELECT und DML-Abfragen der Shard-Schlüssel als konstantes Prädikat angehängt wird. Diese Funktion ist nützlich, wenn Sie zu Aurora PostgreSQL Limitless Database migriert sind und das Schema durch Hinzufügen von Shard-Schlüsseln zu Tabellen denormalisiert haben.

Sie können ein Shard-Schlüsselprädikat automatisch an die bestehende SQL-Logik anhängen, ohne die Semantik der Abfragen zu ändern. Das Anhängen eines aktiven Shard-Schlüsselprädikats erfolgt nur für kompatible Tabellen.

Die aktive Shard-Schlüsselfunktion verwendet die rds_aurora.limitless_active_shard_key Variable, die die folgende Syntax hat:

SET [session | local] rds_aurora.limitless_active_shard_key = '{"col1_value", "col2_value", ...}';

Einige Überlegungen zu aktiven Shard-Schlüsseln und Fremdschlüsseln:

  • Für eine Shard-Tabelle kann eine Fremdschlüsseleinschränkung gelten, wenn die übergeordneten und untergeordneten Tabellen zusammengelegt sind und der Fremdschlüssel eine Obermenge des Shard-Schlüssels ist.

  • Für eine Sharding-Tabelle kann eine Fremdschlüsseleinschränkung für eine Referenztabelle gelten.

  • Eine Referenztabelle kann eine Fremdschlüsseleinschränkung für eine andere Referenztabelle haben.

Nehmen wir an, wir haben eine customers Tabelle, die in der customer_id Spalte geteilt ist.

BEGIN; SET local rds_aurora.limitless_create_table_mode='sharded'; SET local rds_aurora.limitless_create_table_shard_key='{"customer_id"}'; CREATE TABLE customers(customer_id int PRIMARY KEY, name text , email text); COMMIT;

Bei einem aktiven Shard-Schlüsselsatz weisen Abfragen die folgenden Transformationen auf.

SELECT
SET rds_aurora.limitless_active_shard_key = '{"123"}'; SELECT * FROM customers; -- This statement is changed to: SELECT * FROM customers WHERE customer_id = '123'::int;
INSERT
SET rds_aurora.limitless_active_shard_key = '{"123"}'; INSERT INTO customers(name, email) VALUES('Alex', 'alex@example.com'); -- This statement is changed to: INSERT INTO customers(customer_id, name, email) VALUES('123'::int, 'Alex', 'alex@example.com');
AKTUALISIERUNG
SET rds_aurora.limitless_active_shard_key = '{"123"}'; UPDATE customers SET email = 'alex_new_email@example.com'; -- This statement is changed to: UPDATE customers SET email = 'alex_new_email@example.com' WHERE customer_id = '123'::int;
DELETE
SET rds_aurora.limitless_active_shard_key = '{"123"}'; DELETE FROM customers; -- This statement is changed to: DELETE FROM customers WHERE customer_id = '123'::int;
Joins

Wenn Join-Operationen für Tabellen mit einem aktiven Shard-Schlüssel ausgeführt werden, wird das Shard-Schlüssel-Prädikat automatisch allen an der Verknüpfung beteiligten Tabellen hinzugefügt. Dieses automatische Hinzufügen des Shard-Schlüssel-Prädikats erfolgt nur, wenn alle Tabellen in der Abfrage derselben Kollokationsgruppe angehören. Wenn die Abfrage Tabellen aus verschiedenen Kollokationsgruppen umfasst, wird stattdessen ein Fehler ausgelöst.

Gehen Sie davon aus, dass wir orders auch order_details Tabellen haben, die zusammen mit der customers Tabelle angeordnet sind.

SET local rds_aurora.limitless_create_table_mode='sharded'; SET local rds_aurora.limitless_create_table_collocate_with='customers'; SET local rds_aurora.limitless_create_table_shard_key='{"customer_id"}'; CREATE TABLE orders (id int , customer_id int, total_amount int, date date); CREATE TABLE order_details (id int , order_id int, customer_id int, product_name VARCHAR(100), price int); COMMIT;

Rufen Sie die letzten 10 Bestellrechnungen für einen Kunden ab, dessen Kundennummer 10 ist.

SET rds_aurora.limitless_active_shard_key = '{"10"}'; SELECT * FROM customers, orders, order_details WHERE orders.customer_id = customers.customer_id AND order_details.order_id = orders.order_id AND customers.customer_id = 10 order by order_date limit 10;

Diese Abfrage wird wie folgt umgewandelt:

SELECT * FROM customers, orders, order_details WHERE orders.customer_id = customers.customer_id AND orders.order_id = order_details.order_id AND customers.customer_id = 10 AND order_details.customer_id = 10 AND orders.customer_id = 10 AND ORDER BY "order_date" LIMIT 10;
Aktive Shard-Key-kompatible Tabellen

Das Shard-Schlüssel-Prädikat wird nur zu Tabellen hinzugefügt, die mit dem aktiven Shard-Schlüssel kompatibel sind. Eine Tabelle gilt als kompatibel, wenn ihr Shard-Schlüssel dieselbe Anzahl von Spalten enthält, wie in der Variablen angegeben. rds_aurora.limitless_active_shard_key Wenn die Abfrage Tabellen umfasst, die mit dem aktiven Shard-Schlüssel nicht kompatibel sind, gibt das System einen Fehler aus, anstatt mit der Abfrage fortzufahren.

Zum Beispiel:

-- Compatible table SET rds_aurora.limitless_active_shard_key = '{"10"}'; -- The following query works because the customers table is sharded on one column. SELECT * FROM customers; -- Incompatible table SET rds_aurora.limitless_active_shard_key = '{"10","20"}'; -- The following query raises a error because the customers table isn't sharded on two columns. SELECT * FROM customers;