Seleziona le tue preferenze relative ai cookie

Utilizziamo cookie essenziali e strumenti simili necessari per fornire il nostro sito e i nostri servizi. Utilizziamo i cookie prestazionali per raccogliere statistiche anonime in modo da poter capire come i clienti utilizzano il nostro sito e apportare miglioramenti. I cookie essenziali non possono essere disattivati, ma puoi fare clic su \"Personalizza\" o \"Rifiuta\" per rifiutare i cookie prestazionali.

Se sei d'accordo, AWS e le terze parti approvate utilizzeranno i cookie anche per fornire utili funzionalità del sito, ricordare le tue preferenze e visualizzare contenuti pertinenti, inclusa la pubblicità pertinente. Per continuare senza accettare questi cookie, fai clic su \"Continua\" o \"Rifiuta\". Per effettuare scelte più dettagliate o saperne di più, fai clic su \"Personalizza\".

Query a shard singolo nel database Aurora PostgreSQL Limitless - Amazon Aurora

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Query a shard singolo nel database Aurora PostgreSQL Limitless

Una query a shard singolo è una query che può essere eseguita direttamente su uno shard mantenendo la semantica di SQL ACID. Quando viene rilevata una query di questo tipo dal pianificatore di query sul router, il planner la rileva e procede a inviare l'intera query SQL allo shard corrispondente.

Questa ottimizzazione riduce il numero di round trip di rete dal router allo shard, migliorando le prestazioni. Attualmente questa ottimizzazione viene eseguita perINSERT, SELECTUPDATE, e le DELETE interrogazioni.

Esempi di query a frammento singolo

Negli esempi seguenti, abbiamo la tabella condivisacustomers, con la chiave shardcustomer_id, e la tabella di riferimento. 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)
UPDATE
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)

Restrizioni per le query a shard singolo

Le query a shard singolo presentano le seguenti restrizioni:

Funzioni

Se una query a shard singolo contiene una funzione, la query è idonea per l'ottimizzazione a shard singolo solo se si applica una delle seguenti condizioni:

Visualizzazioni

Se una query contiene una o più viste, l'ottimizzazione a shard singolo è disabilitata per la query se presenta una delle seguenti condizioni:

  • Qualsiasi vista ha l'security_barrierattributo.

  • Gli oggetti utilizzati nella query richiedono più privilegi utente. Ad esempio, una query contiene due visualizzazioni che vengono eseguite da due utenti diversi.

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)
Istruzioni PREPARE ed EXECUTE

Aurora PostgreSQL Limitless Database supporta l'ottimizzazione a shard singolo per le istruzioni preparate. SELECT

Tuttavia, se l'istruzione preparata è un UPDATE o DELETE e contiene una variabile preparata, il pianificatore di query rifiuta l'ottimizzazione a shard singolo per quella query. Ciò è illustrato negli esempi seguenti: l'Single Shard Optimizedindicatore è mancante.

postgres_limitless=> PREPARE testStmt AS SELECT customer_name FROM customers c WHERE c.customer_id = $1; PREPARE postgres_limitless=> EXECUTE testStmt(1); customer_name --------------- (0 rows)
postgres_limitless=> EXPLAIN verbose EXECUTE testStmt(1); 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: 1520926022284463170 Remote SQL: SELECT customer_name FROM public.customers c WHERE (customer_id = $1) Query Identifier: 1520926022284463170 (11 rows)
PL/pgSQL

Per le interrogazioni con PL/pgSQL variables are run as implicitly prepared statements. If a query contains any PL/pgSQL variabili, il pianificatore di query rifiuta l'ottimizzazione a shard singolo.

L'ottimizzazione è supportata nelle variabili. PL/pgSQL block if the statement doesn't contain any PL/pgSQL

Unioni completamente qualificate (esplicite)

L'ottimizzazione a shard singolo si basa sull'eliminazione delle partizioni. L'ottimizzatore PostgreSQL elimina le partizioni in base a condizioni costanti. Se Aurora PostgreSQL Limitless Database rileva che tutte le partizioni e le tabelle rimanenti si trovano sullo stesso shard, contrassegna la query come idonea per l'ottimizzazione a shard singolo. Tutte le condizioni di filtro devono essere esplicite affinché l'eliminazione delle partizioni funzioni. Aurora PostgreSQL Limitless Database non è in grado di eliminare le partizioni senza uno o più predicati di join o filtrare i predicati sulle chiavi shard di ogni tabella condivisa nell'istruzione.

Supponiamo di aver partizionato le tabelle, e in base alla colonna. customers orders order_details customer_id In questo schema, l'applicazione cerca di conservare tutti i dati di un cliente su un singolo shard.

Considera la query seguente:

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;

Questa query recupera tutti i dati di un cliente ()c.customer_id = 1. I dati di questo cliente si trovano su un singolo shard, ma Aurora PostgreSQL Limitless Database non qualifica questa query come query a shard singolo. Il processo di ottimizzazione per la query è il seguente:

  1. L'ottimizzatore può eliminare le partizioni per customers e in orders base alla seguente condizione:

    c.customer_id = 1 c.customer_id = o.customer_id o.customer_id = 1 (transitive implicit condition)
  2. L'ottimizzatore non può eliminare alcuna partizione perché non esiste una condizione costante sulla tabella. order_details

  3. L'ottimizzatore conclude di aver letto tutte le partizioni da. order_details Pertanto, la query non può essere qualificata per l'ottimizzazione a shard singolo.

Per renderla una query a shard singolo, aggiungiamo la seguente condizione di unione esplicita:

o.customer_id = od.customer_id

La query modificata ha il seguente aspetto:

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;

Ora l'ottimizzatore può eliminare le partizioni per. order_details La nuova query diventa una query a frammento singolo e si qualifica per l'ottimizzazione.

Impostazione di una chiave shard attiva

Questa funzionalità consente di impostare una singola chiave shard durante l'interrogazione del database, facendo sì che tutte SELECT le query DML vengano aggiunte con la chiave shard come predicato costante. Questa funzionalità è utile se hai effettuato la migrazione ad Aurora PostgreSQL Limitless Database e hai denormalizzato lo schema aggiungendo chiavi shard alle tabelle.

È possibile aggiungere automaticamente un predicato di chiave shard alla logica SQL esistente, senza modificare la semantica delle query. L'aggiunta di un predicato di chiave shard attiva viene eseguita solo per le tabelle compatibili.

La funzionalità active shard key utilizza la rds_aurora.limitless_active_shard_key variabile, che ha la seguente sintassi:

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

Alcune considerazioni sulle chiavi shard attive e sulle chiavi esterne:

  • Una tabella condivisa può avere un vincolo di chiave esterna se le tabelle principale e secondaria sono collocate e la chiave esterna è un superset della chiave shard.

  • Una tabella condivisa può avere un vincolo di chiave esterna rispetto a una tabella di riferimento.

  • Una tabella di riferimento può avere un vincolo di chiave esterna rispetto a un'altra tabella di riferimento.

Supponiamo di avere una customers tabella condivisa sulla colonna. customer_id

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;

Con un set di chiavi shard attivo, le query hanno le seguenti trasformazioni.

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');
UPDATE
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;
Join

Quando si eseguono operazioni di join su tabelle con una chiave shard attiva, il predicato della chiave shard viene aggiunto automaticamente a tutte le tabelle coinvolte nel join. Questa aggiunta automatica del predicato della chiave shard si verifica solo quando tutte le tabelle della query appartengono allo stesso gruppo di collocazione. Se la query riguarda tabelle di gruppi di collocazione diversi, viene invece generato un errore.

Supponiamo di avere orders anche delle order_details tabelle che sono collocate con la customers tabella.

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;

Recupera le ultime 10 fatture d'ordine per un cliente il cui ID cliente è 10.

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;

Questa interrogazione viene trasformata nella seguente:

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;
Tabelle compatibili con Active Shard Key

Il predicato della chiave shard viene aggiunto solo alle tabelle compatibili con la chiave shard attiva. Una tabella è considerata compatibile se ha lo stesso numero di colonne nella chiave shard specificato nella variabile. rds_aurora.limitless_active_shard_key Se la query riguarda tabelle incompatibili con la chiave shard attiva, il sistema genera un errore invece di procedere con la query.

Per esempio:

-- 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;
PrivacyCondizioni del sitoPreferenze cookie
© 2025, Amazon Web Services, Inc. o società affiliate. Tutti i diritti riservati.