SQLcostrutti per interrogazioni parallele in Aurora My SQL - 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à.

SQLcostrutti per interrogazioni parallele in Aurora My SQL

Nella sezione seguente, puoi trovare maggiori dettagli sul motivo per cui determinate SQL istruzioni utilizzano o non utilizzano la query parallela. Questa sezione descrive anche come le SQL funzionalità di Aurora My interagiscono con le query parallele. Queste informazioni dettagliate possono consentirti di diagnosticare i problemi relativi alle prestazioni di un cluster che utilizza le query in parallelo o di comprendere il modo in cui queste vengono applicate a un particolare carico di lavoro.

La decisione di utilizzare la funzione di query in parallelo dipende da molti fattori che intervengono al momento dell'esecuzione dell'istruzione. Di conseguenza, per certe query, tale funzionalità può essere utilizzata sempre, mai o solo in determinate circostanze.

Suggerimento

Quando visualizzi questi esempi inHTML, puoi usare il widget Copia nell'angolo superiore destro di ogni elenco di codici per copiare il SQL codice e provare tu stesso. L'utilizzo del widget Copia evita di copiare i caratteri aggiuntivi attorno alle righe del prompt mysql> e della continuazione ->.

EXPLAINdichiarazione

Come mostrato negli esempi in questa sezione, l'istruzione EXPLAIN indica se ogni fase di una query è idonea alla funzionalità di query in parallelo. Indica inoltre quali aspetti di una query possono essere trasferiti a un livello di storage. Di seguito sono riportati gli elementi più importanti del piano query:

  • Un valore differente da NULL per la colonna key suggerisce che la query può essere eseguita in modo efficace mediante ricerche di indice e che l'utilizzo della funzionalità di query in parallelo è improbabile.

  • Un valore basso della colonna rows (ovvero un valore non in milioni) suggerisce che la query non ha accesso a dati sufficienti per giustificare l'utilizzo della funzionalità di query in parallelo e che quindi è improbabile. Ciò significa che la query parallela è improbabile.

  • La colonna Extra indica se l'uso della funzionalità di query in parallelo è previsto. Questo output è simile all'esempio seguente.

    Using parallel query (A columns, B filters, C exprs; D extra)

    Il numero columns rappresenta il numero di colonne a cui il blocco di query fa riferimento.

    Il numero filters rappresenta il numero di predicati WHERE che rappresentano un semplice confronto tra un valore di colonna e una costante. Il confronto può ricercare un'uguaglianza, una disuguaglianza o un intervallo. Aurora può parallelizzare questi tipi di predicati in maniera più efficace.

    Il numero exprs rappresenta il numero di espressioni come chiamate di funzione, operatori o altre espressioni che possono anche essere parallelizzate, sebbene meno efficacemente rispetto a una condizione di filtro.

    Il numero extra rappresenta il numero di espressioni che non è possibile trasferire e che sono eseguite dal nodo head.

Consideriamo ad esempio il seguente output EXPLAIN.

mysql> explain select p_name, p_mfgr from part -> where p_brand is not null -> and upper(p_type) is not null -> and round(p_retailprice) is not null; +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+

Le informazioni nella colonna Extra mostrano che cinque colonne sono estratte da ogni riga per valutare le condizioni della query e costruire il set di risultati. Un predicato WHERE comporta un filtro, ovvero una colonna che è testata direttamente nella clausola WHERE. Due clausole WHERE richiedono la valutazione di espressioni più complesse, che in questo caso implicano chiamate di funzione. Il campo 0 extra conferma che tutte le operazioni nella clausola WHERE sono trasferite al livello di storage nell'ambito dell'elaborazione di query in parallelo.

Nei casi in cui una query in parallelo non viene scelta, puoi in genere dedurre il motivo dalle altre colonne dell'output EXPLAIN. Ad esempio, il valore rows può essere troppo basso oppure la colonna possible_keys può indicare che la query è in grado di utilizzare una ricerca di indice anziché l'analisi di una grande quantità di dati. Nell'esempio seguente viene illustrata una query in cui l'ottimizzatore può stimare che la query eseguirà la scansione solo di un numero ridotto di righe. Lo fa in base alle caratteristiche della chiave primaria. In tal caso, nessuna query in parallelo è necessaria.

mysql> explain select count(*) from part where p_partkey between 1 and 100; +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | 1 | SIMPLE | part | range | PRIMARY | PRIMARY | 4 | NULL | 99 | Using where; Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

L'output che indica se una query in parallelo sarà utilizzata prende in considerazione tutti i fattori presenti al momento dell'esecuzione dell'istruzione EXPLAIN. L'ottimizzatore può effettuare una scelta differente quando la query è in esecuzione, se la situazione è cambiata nel frattempo. Ad esempio, EXPLAIN può indicare che un'istruzione utilizzerà una query in parallelo. Tuttavia, quando successivamente la query viene eseguita, può non usare la query in parallelo in base alle condizioni in quel momento. Tali condizioni possono includere diverse altre query parallele in esecuzione contemporaneamente. Possono anche includere righe che vengono eliminate dalla tabella, un nuovo indice in fase di creazione, troppo tempo che passa all'interno di una transazione aperta e così via.

WHEREClausola

Per utilizzare l'ottimizzazione mediante query in parallelo, una query deve includere una clausola WHERE.

Questa ottimizzazione accelera molti tipi di espressioni utilizzati nella clausola WHERE:

  • Confronti semplici tra un valore di colonna e una costante, noti come filtri. Questi confronti sono ottimali quando trasferiti al livello di storage. Il numero di espressioni di filtro in una query è indicato nell'output EXPLAIN.

  • Anche altri tipi di espressioni nella clausola WHERE sono trasferiti al livello di storage quando possibile. Il numero di tali espressioni in una query è indicato nell'output EXPLAIN. Queste espressioni possono essere chiamate di funzione, operatori LIKE, espressioni CASE e così via.

  • Alcune funzioni e operatori non sono attualmente trasferiti dalla query in parallelo. Il numero di tali espressioni in una query è indicato come contatore extra nell'output EXPLAIN. Il resto della query può ancora utilizzare la funzionalità di query in parallelo.

  • Sebbene le espressioni nell'elenco di selezione non siano trasferite, le query contenenti tali funzioni possono ancora beneficiare di una riduzione del traffico di rete per i risultati intermedi delle query in parallelo. Ad esempio, le query che chiamano funzioni di aggregazione nell'elenco di selezione possono beneficiare delle query in parallelo, anche se le funzioni di aggregazione non sono trasferite.

Ad esempio, la query seguente esegue un'analisi dell'intera tabella ed elabora tutti i valori per la colonna P_BRAND: Tuttavia, non utilizza la funzionalità di query in parallelo in quanto la query non include alcuna clausola WHERE.

mysql> explain select count(*), p_brand from part group by p_brand; +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | 1 | SIMPLE | part | ALL | NULL | NULL | NULL | NULL | 20427936 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+

Al contrario, la query seguente include predicati WHERE che filtrano i risultati, di conseguenza la funzionalità di query in parallelo può essere utilizzata:

mysql> explain select count(*), p_brand from part where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 -> group by p_brand; +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using temporary; Using filesort; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+...+----------+-------------------------------------------------------------------------------------------------------------+

Se l'ottimizzatore stima che il numero di righe restituite per un blocco di query è basso, la funzionalità di query in parallelo non viene utilizzata per quel blocco. L'esempio seguente mostra uno scenario in cui un operatore "maggiore di" nella colonna di chiave primaria viene applicato a milioni di righe, comportando l'utilizzo della funzionalità di query in parallelo. Per l'operatore inverso "minore di" viene stimata l'applicazione soltanto ad alcune righe e tale funzionalità non è quindi utilizzata.

mysql> explain select count(*) from part where p_partkey > 10; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+ mysql> explain select count(*) from part where p_partkey < 10; +----+...+------+--------------------------+ | id |...| rows | Extra | +----+...+------+--------------------------+ | 1 |...| 9 | Using where; Using index | +----+...+------+--------------------------+

linguaggio di definizione dei dati (DDL)

In Aurora My SQL versione 2, la query parallela è disponibile solo per le tabelle per le quali non sono in sospeso operazioni fast data definition language (DDL). In Aurora My SQL versione 3, è possibile utilizzare la query parallela su una tabella contemporaneamente a un'operazione istantaneaDDL.

Instant DDL in Aurora My SQL versione 3 sostituisce la funzionalità veloce DDL di Aurora My versione 2. SQL Per informazioni su instantDDL, vedi. DDL istantaneo (Aurora MySQL versione 3)

Tipi di dati di colonna

In Aurora My SQL versione 3, la query parallela può funzionare con tabelle contenenti colonne con tipi di datiTEXT, BLOBJSON, e. GEOMETRY Può funzionare anche con colonne VARCHAR e CHAR con una lunghezza massima dichiarata superiore a 768 byte. Se la query fa riferimento a colonne contenenti tipi di oggetti così grandi, il lavoro aggiuntivo per recuperarli aggiunge un sovraccarico all'elaborazione delle query. In tal caso, verificare se la query può omettere i riferimenti a tali colonne. In caso contrario, eseguire i valori di riferimento per confermare se tali query sono più veloci con la query parallela attivata o disattivata.

In Aurora My SQL versione 2, la query parallela presenta le seguenti limitazioni per i tipi di oggetti di grandi dimensioni:

  • I tipi di dati TEXT, BLOB, JSON e GEOMETRY non sono supportati con le query in parallelo. Una query che fa riferimento alle colonne di questi tipi non può utilizzare le query in parallelo.

  • Le colonne a lunghezza variabile (tipi di dati VARCHAR e CHAR) sono compatibili con le query in parallelo fino a una lunghezza dichiarata massima di 768 byte. Una query che fa riferimento a qualsiasi colonna dei tipi dichiarati con una lunghezza massima superiore non può utilizzare le query in parallelo. Per le colonne che utilizzano set di caratteri multibyte, il limite di byte prende in considerazione il numero massimo di byte nel set di caratteri. Ad esempio, per il set di caratteri utf8mb4 (che ha un limite di lunghezza di 4 byte), una colonna VARCHAR(192) è compatibile con le query in parallelo mentre una colonna VARCHAR(193) non lo è.

Tabelle partizionate

È possibile utilizzare tabelle partizionate con query parallele in Aurora My versione 3. SQL Poiché le tabelle partizionate sono rappresentate internamente come più tabelle più piccole, una query che utilizza query parallele su una tabella non partizionata potrebbe non utilizzare query parallele su una tabella partizionata identica. Aurora My SQL valuta se ogni partizione è sufficientemente grande da qualificarsi per l'ottimizzazione delle query parallele, invece di valutare la dimensione dell'intera tabella. Controllare se la variabile di stato Aurora_pq_request_not_chosen_small_table viene incrementata se una query in una tabella partizionata non utilizza una query parallela quando ci si aspetta.

Ad esempio, si consideri una tabella partizionata con PARTITION BY HASH (column) PARTITIONS 2 e un’altra tabella partizionata con PARTITION BY HASH (column) PARTITIONS 10. Nella tabella con due partizioni, le partizioni sono cinque volte più grandi della tabella con dieci partizioni. Pertanto, è più probabile che la query parallela venga utilizzata per le query sulla tabella con meno partizioni. Nell'esempio seguente, la tabella PART_BIG_PARTITIONS ha due partizioni e la PART_SMALL_PARTITIONS ha dieci partizioni. Con dati identici, è più probabile che la query parallela venga utilizzata per la tabella con meno partizioni di grandi dimensioni.

mysql> explain select count(*), p_brand from part_big_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | part_big_partitions | p0,p1 | Using where; Using temporary; Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra; 1 group-bys, 1 aggrs) | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ mysql> explain select count(*), p_brand from part_small_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+-----------------------+-------------------------------+------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+-----------------------+-------------------------------+------------------------------+ | 1 | SIMPLE | part_small_partitions | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | Using where; Using temporary | +----+-------------+-----------------------+-------------------------------+------------------------------+

Funzioni aggregate, clausole BY e clausole GROUP HAVING

Le query che implicano funzioni di aggregazione sono spesso adatte alle query in parallelo, in quanto comportano l'analisi di un gran numero di righe in tabelle di grandi dimensioni.

In Aurora My SQL 3, la query parallela può ottimizzare le chiamate di funzioni aggregate nell'elenco di selezione e nella clausola. HAVING

Prima di Aurora My SQL 3, le chiamate alle funzioni aggregate nell'elenco di selezione o nella HAVING clausola non venivano trasferite al livello di archiviazione. Tuttavia, la funzionalità di query in parallelo può sempre migliorare le prestazioni di queste query con funzioni di aggregazione. A questo proposito, estrae dapprima in parallelo i valori di colonna dalle pagine di dati non elaborati nel livello di storage. Ritrasmette quindi quei valori al nodo head in un formato di tupla compatto anziché come pagine di dati complete. Come sempre, la query richiede almeno un predicato WHERE affinché la funzione di query in parallelo sia attivata.

Gli esempi semplici seguenti illustrano i tipi di query di aggregazione che possono beneficiare della funzionalità di query in parallelo restituendo risultati intermedi in formato compatto al nodo head, filtrando le righe non corrispondenti dai risultati intermedi oppure con entrambe le operazioni.

mysql> explain select sql_no_cache count(distinct p_brand) from part where p_mfgr = 'Manufacturer#5'; +----+...+----------------------------------------------------------------------------+ | id |...| Extra | +----+...+----------------------------------------------------------------------------+ | 1 |...| Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------------------------------------------------------------------------+ mysql> explain select sql_no_cache p_mfgr from part where p_retailprice > 1000 group by p_mfgr having count(*) > 100; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (3 columns, 0 filters, 1 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

Chiamate di funzione nella clausola WHERE

Aurora consente di applicare l'ottimizzazione mediante query in parallelo per le chiamate alla maggior parte delle funzioni integrate nella clausola WHERE. La parallelizzazione di queste chiamate di funzione scarica parte del CPU lavoro dal nodo principale. La valutazione delle funzioni di predicato in parallelo durante le prime fasi di una query consente a Aurora di ridurre al minimo la quantità di dati trasmessi ed elaborati nelle fasi successive.

Attualmente, la parallelizzazione non viene applicata alle chiamate di funzione nell'elenco di selezione. Queste funzioni sono valutate dal nodo head anche se chiamate di funzione identiche sono presenti nella clausola WHERE. I valori di origine delle colonne pertinenti sono inclusi nelle tuple ritrasmesse dai nodi di storage al nodo head. Il nodo head esegue tutte le trasformazioni come UPPER, CONCATENATE, ecc., allo scopo di generare i valori finali del set di risultati.

Nell'esempio seguente, una query in parallelo parallelizza la chiamata a LOWER in quanto è presente nella clausola WHERE. La query in parallelo non viene applicata alle chiamate a SUBSTR e UPPER in quanto queste sono presenti nell'elenco di selezione.

mysql> explain select sql_no_cache distinct substr(upper(p_name),1,5) from part -> where lower(p_name) like '%cornflower%' or lower(p_name) like '%goldenrod%'; +----+...+---------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+---------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+...+---------------------------------------------------------------------------------------------+

Le stesse considerazioni sono valide per altre espressioni, come espressioni CASE o operatori LIKE. L'esempio seguente mostra una query in parallelo che valuta l'espressione CASE e gli operatori LIKE nella clausola WHERE.

mysql> explain select p_mfgr, p_retailprice from part -> where p_retailprice > case p_mfgr -> when 'Manufacturer#1' then 1000 -> when 'Manufacturer#2' then 1200 -> else 950 -> end -> and p_name like '%vanilla%' -> group by p_retailprice; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (4 columns, 0 filters, 2 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

LIMITClausola

Le query in parallelo non sono correntemente utilizzate per blocchi di query che includono una clausola LIMIT. Le query in parallelo possono ancora essere utilizzate per fasi di query precedenti con le clausole GROUPBY, ORDER BY oppure con join.

Operatori di confronto

L'ottimizzatore stima il numero di righe da analizzare per valutare gli operatori di confronto e determina se utilizzare la funzionalità di query in parallelo in base a quella stima.

Il primo esempio qui sotto mostra che un confronto delle uguaglianze con la colonna di chiave primaria può essere eseguito in modo efficace senza la funzionalità di query in parallelo. Il secondo esempio mostra che un confronto simile con una colonna non indicizzata richiede l'analisi di milioni di righe e che di conseguenza può beneficiare della funzionalità di query in parallelo.

mysql> explain select * from part where p_partkey = 10; +----+...+------+-------+ | id |...| rows | Extra | +----+...+------+-------+ | 1 |...| 1 | NULL | +----+...+------+-------+ mysql> explain select * from part where p_type = 'LARGE BRUSHED BRASS'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+

Le stesse considerazioni sono valide per i test di diseguaglianza e i confronti di intervalli come "minore di", "maggiore di" o "uguale a" oppure BETWEEN. L'ottimizzatore stima il numero di righe da analizzare e in base al volume globale di operazioni di I/O determina se l'utilizzo della funzionalità di query in parallelo è giustificato.

Join

Le query join con tabelle di grandi dimensioni comportano in genere operazioni con grandi quantità di dati che beneficiano dell'ottimizzazione mediante query in parallelo. I confronti dei valori di colonna tra molteplici tabelle (ovvero i predicati di join stessi) non sono attualmente parallelizzati. La funzionalità di query in parallelo può tuttavia trasferire una parte dell'elaborazione interna per altre fasi di join, come la costruzione del filtro Bloom durante un hash join. Inoltre, può essere applicata a query join anche senza una clausola WHERE. Di conseguenza, una query join è un'eccezione alla regola secondo cui una clausola WHERE è necessaria per utilizzare la query in parallelo.

Ogni fase dell'elaborazione di un join è valutata per determinare se è idonea per la funzionalità di query in parallelo. Se più fasi possono utilizzare tale funzionalità, sono eseguite in sequenza. Ogni query join viene pertanto contabilizzata come singola sessione di query in parallelo in termini di limiti di simultaneità.

Ad esempio, quando una query join include predicati WHERE per filtrare le righe di una delle tabelle unite in join, tale opzione di filtraggio può utilizzare la funzionalità di query in parallelo. Un altro esempio consiste in una query join che utilizza il meccanismo di hash join per unire in join una tabella di grandi dimensioni e una di piccole dimensioni. In tal caso, la funzionalità di query in parallelo potrebbe essere applicata all'analisi delle tabelle per generare la struttura di dati del filtro Bloom.

Nota

La query in parallelo viene in genere utilizzata per quei tipi di query che richiedono un uso intensivo di risorse che traggono vantaggio dall'ottimizzazione dell'hash join. Il metodo per attivare l'ottimizzazione dell'hash join dipende dalla versione di Aurora MySQL. Per informazioni dettagliate su ogni versione, consultare Abilitazione dell'hash join per cluster di query parallele. Per informazioni su come utilizzare i join hash in modo efficace, vedere Ottimizzazione delle query Aurora SQL My join di grandi dimensioni con hash join.

mysql> explain select count(*) from orders join customer where o_custkey = c_custkey; +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | id |...| table | type | possible_keys | key |...| rows | Extra | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | 1 |...| customer | index | PRIMARY | c_nationkey |...| 15051972 | Using index | | 1 |...| orders | ALL | o_custkey | NULL |...| 154545408 | Using join buffer (Hash Join Outer table orders); Using parallel query (1 columns, 0 filters, 1 exprs; 0 extra) | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+

Per una query join che utilizza il meccanismo di ciclo nidificato, il blocco di ciclo nidificato più esterno può utilizzare la funzionalità di query in parallelo. L'utilizzo delle query in parallelo dipende dai fattori usuali, come la presenza di condizioni di filtro supplementari nella clausola WHERE.

mysql> -- Nested loop join with extra filter conditions can use parallel query. mysql> explain select count(*) from part, partsupp where p_partkey != ps_partkey and p_name is not null and ps_availqty > 0; +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | | 1 | SIMPLE | partsupp |...| 78164450 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+

Sottoquery

Il blocco di query esterno e il blocco di sottoquery interno possono utilizzare ciascuna query parallela o meno. Se lo fanno si basa sulle solite caratteristiche della tabella, clausola WHERE e così via, per ogni blocco. Ad esempio, la query seguente utilizza tale funzionalità per il blocco di sottoquery ma non per il blocco esterno.

mysql> explain select count(*) from part where --> p_partkey < (select max(p_partkey) from part where p_name like '%vanilla%'); +----+-------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| NULL | Impossible WHERE noticed after reading const tables | | 2 | SUBQUERY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+-------------+...+----------+----------------------------------------------------------------------------+

Attualmente, le sottoquery correlate non possono utilizzare l'ottimizzazione mediante query in parallelo.

UNION

Ogni blocco di query in una query UNION può utilizzare o meno la funzionalità di query in parallelo in base alle caratteristiche abituali della tabella, della clausola WHERE, ecc., per ogni parte della query UNION.

mysql> explain select p_partkey from part where p_name like '%choco_ate%' -> union select p_partkey from part where p_name like '%vanil_a%'; +----+----------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+----------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | 2 | UNION |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | NULL | UNION RESULT | <union1,2> |...| NULL | Using temporary | +----+--------------+...+----------+----------------------------------------------------------------------------+
Nota

Ogni clausola UNION nella query viene eseguita in modo sequenziale. Anche se la query include molteplici fasi che utilizzano la funzionalità di query in parallelo, esegue sempre un'unica query in parallelo. Di conseguenza, anche una query complessa con più fasi viene contabilizzata come una sola query per il limite di query in parallelo simultanee.

Visualizzazioni

L'ottimizzatore riscrive le query con una visualizzazione come query più lunga che utilizza le tabelle sottostanti. La query in parallelo funziona quindi nello stesso modo indipendentemente dal fatto che i riferimenti delle tabelle siano visualizzazioni o tabelle reali. Tutte le considerazioni sull'utilizzo o meno della funzionalità di query in parallelo per una query nonché su quali parti vengono trasferite, si applicano alla query riscritta finale.

Ad esempio, il piano query seguente mostra la definizione di una visualizzazione che in genere non utilizza le query in parallelo. Quando la vista viene interrogata con WHERE clausole aggiuntive, Aurora My utilizza la query parallela. SQL

mysql> create view part_view as select * from part; mysql> explain select count(*) from part_view where p_partkey is not null; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 0 filters, 0 exprs; 1 extra) | +----+...+----------+----------------------------------------------------------------------------+

Istruzioni del linguaggio di manipolazione dei dati () DML

L'istruzione INSERT può utilizzare la funzionalità di query in parallelo per la fase SELECT dell'elaborazione, se la parte SELECT soddisfa le altre condizioni relative a tale funzionalità.

mysql> create table part_subset like part; mysql> explain insert into part_subset select * from part where p_mfgr = 'Manufacturer#1'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
Nota

In genere, dopo un'istruzione INSERT, i dati delle righe appena inserite si trovano nel pool di buffer. Di conseguenza, una tabella può non essere idonea per la funzionalità di query in parallelo subito dopo l'inserimento di un gran numero di righe. Successivamente, dopo la rimozione dei dati dal pool di buffer durante il funzionamento normale, le query sulla tabella possono iniziare a utilizzare di nuovo la funzionalità di query in parallelo.

L'istruzione CREATE TABLE AS SELECT non utilizza la funzionalità di query in parallelo anche se la porzione SELECT dell'istruzione fosse idonea a farlo. L'DDLaspetto di questa dichiarazione la rende incompatibile con l'elaborazione parallela delle interrogazioni. Nell'istruzione INSERT ... SELECT, la porzione SELECT può invece utilizzare la funzionalità di query in parallelo.

Le query in parallelo non sono mai utilizzate per le istruzioni DELETE o UPDATE, indipendentemente dalla dimensione della tabella e dei predicati nella clausola WHERE.

mysql> explain delete from part where p_name is not null; +----+-------------+...+----------+-------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+-------------+ | 1 | SIMPLE |...| 20427936 | Using where | +----+-------------+...+----------+-------------+

Transazioni e blocco

Puoi utilizzare tutti i livelli di isolamento sull'istanza primaria Aurora.

Sulle istanze database di lettura Aurora, la query parallela si applica alle istruzioni eseguite nel livello di isolamento REPEATABLE READ. Aurora My SQL versione 2.09 o successiva può anche utilizzare il livello di READ COMMITTED isolamento sulle istanze Reader DB. REPEATABLE READè il livello di isolamento predefinito per le istanze DB del lettore Aurora. Per utilizzare il livello di isolamento READ COMMITTED sulle istanze DB del lettore è necessario impostare l'opzione di configurazione aurora_read_replica_read_committed a livello di sessione. Il livello di READ COMMITTED isolamento per le istanze Reader è conforme al comportamento standard. SQL Tuttavia, l'isolamento è meno rigoroso per le istanze di lettura rispetto a quando le query utilizzano il livello di isolamento READ COMMITTED sull'istanza di scrittura.

Per ulteriori informazioni sui livelli di isolamento Aurora, in particolare sulle differenze su READ COMMITTED fra le istanze di scrittura e lettura, consultare Aurora I miei SQL livelli di isolamento.

Al termine di una transazione di grandi dimensioni, le statistiche della tabella possono non essere aggiornate. Queste statistiche possono necessitare di un'istruzione ANALYZE TABLE affinché Aurora sia in grado di stimare accuratamente il numero di righe. Un'DMListruzione su larga scala potrebbe anche portare una parte sostanziale dei dati della tabella nel buffer pool. La presenza di questi dati nel pool di buffer può implicare un utilizzo meno frequente della funzionalità di query in parallelo per quella tabella fino a che i dati non vengono rimossi dal pool.

Quando la tua sessione è in una transazione di lunga durata (per impostazione predefinita, 10 minuti), le altre query in quella sessione non utilizzano la funzionalità di query in parallelo. È anche possibile che si verifichi un timeout durante una singola query di lunga durata. Questo tipo di timeout può verificarsi se la durata della query è più lunga dell'intervallo massimo (attualmente 10 minuti) prima dell'inizio dell'elaborazione di query in parallelo.

Puoi limitare il rischio di un'esecuzione accidentale delle transazioni di lunga durata impostando autocommit=1 nelle sessioni mysql in cui esegui query ad hoc (uniche). Anche un'istruzione SELECT relativa a una tabella inizia una transazione creando una visualizzazione di lettura. Una visualizzazione di lettura è un set di dati coerente per le query successive che viene conservato fino al commit della transazione. Tieni presente questa restrizione anche quando usi JDBC o ODBC applicazioni con Aurora, poiché tali applicazioni potrebbero essere eseguite con autocommit l'impostazione disattivata.

L'esempio seguente mostra come, con l'impostazione autocommit disattivata, l'esecuzione di una query su una tabella crea una visualizzazione di lettura che implicitamente avvia una transazione. Le query eseguite subito dopo possono ancora utilizzare la funzionalità di query in parallelo. Tuttavia, dopo una pausa di alcuni minuti, le query non sono più idonee per tale funzionalità. Termina la transazione con COMMIT o ROLLBACK per ripristinare l'idoneità.

mysql> set autocommit=0; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+ mysql> select sleep(720); explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +------------+ | sleep(720) | +------------+ | 0 | +------------+ 1 row in set (12 min 0.00 sec) +----+...+---------+-------------+ | id |...| rows | Extra | +----+...+---------+-------------+ | 1 |...| 2976129 | Using where | +----+...+---------+-------------+ mysql> commit; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+

Per determinare quante volte le query non erano idonee per le query in parallelo perché parte di transazioni di lunga durata, verifica la variabile di stato Aurora_pq_request_not_chosen_long_trx.

mysql> show global status like '%pq%trx%'; +---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | Aurora_pq_request_not_chosen_long_trx | 4 | +-------------------------------+-------+

Qualsiasi istruzione SELECT che acquisisce blocchi, come la sintassi SELECT FOR UPDATE o SELECT LOCK IN SHARE MODE, non può utilizzare la funzionalità di query in parallelo.

Le query in parallelo possono essere utilizzate con una tabella bloccata da un'istruzione LOCK TABLES.

mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055'; +----+...+-----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+-----------+----------------------------------------------------------------------------+ | 1 |...| 154545408 | Using where; Using parallel query (3 columns, 1 filters, 0 exprs; 0 extra) | +----+...+-----------+----------------------------------------------------------------------------+ mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055' for update; +----+...+-----------+-------------+ | id |...| rows | Extra | +----+...+-----------+-------------+ | 1 |...| 154545408 | Using where | +----+...+-----------+-------------+

Indici B-Tree

Le statistiche raccolte da un'istruzione ANALYZE TABLE consentono all'ottimizzatore di stabilire quando utilizzare la funzionalità di query in parallelo o le ricerche di indice in funzione delle caratteristiche dei dati di ogni colonna. Mantieni aggiornate le statistiche eseguendo ANALYZE TABLE DML operazioni che apportano modifiche sostanziali ai dati all'interno di una tabella.

Se le ricerche di indice sono in grado di eseguire efficacemente una query senza l'analisi di un grande volume di dati, Aurora può utilizzare le ricerche di indice. In questo modo, si evita l'overhead dell'elaborazione di query in parallelo. Esistono inoltre limiti di simultaneità sul numero di query in parallelo che possono essere eseguite simultaneamente su qualsiasi cluster di database Aurora. Assicurati di seguire le best practice per l'indicizzazione delle tabelle, di modo che le query più frequenti e che utilizzano maggiormente la simultaneità ricorrano alle ricerche di indice.

Indici di ricerca a testo completo (FTS)

Al momento, le query in parallelo non sono utilizzate per le tabelle che contengono un indice di ricerca full-text, indipendentemente dal fatto che la query faccia riferimento a tali colonne indicizzate o che utilizzi l'operatore MATCH.

Colonne virtuali

Attualmente, la query parallela non viene utilizzata per le tabelle che contengono una colonna virtuale, indipendentemente dal fatto che la query faccia riferimento a colonne virtuali.

Meccanismi di caching integrati

Aurora include meccanismi di caching integrati, ovvero il pool di buffer e la cache di query L'ottimizzatore Aurora sceglie tra questi meccanismi di caching e la funzionalità di query in parallelo a seconda di quale è più efficace per una determinata query.

Quando una query in parallelo filtra le righe e trasforma ed estrae i valori di colonna, i dati sono ritrasmessi al nodo head come tuple anziché pagine di dati. Di conseguenza, l'esecuzione di una query in parallelo non aggiunge pagine al pool di buffer o rimuove pagine presenti nel pool di buffer.

Aurora verifica il numero di pagine di dati della tabella presenti nel pool di buffer e quale proporzione di quei dati quel numero rappresenta. Aurora si basa su tali informazioni per determinare se è più efficace utilizzare la funzionalità di query parallela (e ignorare i dati nel pool di buffer). In alternativa, Aurora può utilizzare il percorso di elaborazione di query non in parallelo, che si avvale dei dati nella cache del pool di buffer. Le pagine memorizzate nella cache e l'impatto delle query con una grande quantità di dati sulle operazioni di caching e rimozione dipendono dalle impostazioni di configurazione relative al pool di buffer. Può quindi rivelarsi difficile prevedere se una specifica query utilizza la funzionalità di query in parallelo, poiché la scelta dipende dai dati che si trovano nel pool di buffer e che cambiano costantemente.

Inoltre, Aurora impone limiti di simultaneità per le query in parallelo. Poiché non tutte le query utilizzano la funzionalità di query in parallelo, una parte importante dei dati delle tabelle a cui hanno accesso più query simultaneamente si trova nel pool di buffer. Di conseguenza, Aurora spesso non sceglie queste tabelle per le query in parallelo.

Quando esegui una sequenza di query non in parallelo sulla stessa tabella, la prima query può risultare lenta in quanto i dati non sono presenti nel pool di buffer. La seconda query e quelle successive saranno molto più rapide in quanto il pool di buffer conterrà già dei dati. Le query in parallelo in genere forniscono prestazioni costanti sin dalla prima query su una tabella. Quando esegui test di prestazioni, compara le query non in parallelo con un pool di buffer a caldo e uno a freddo. In alcuni casi, i risultati con un pool di buffer a caldo sono comparabili a quelli delle query in parallelo. In questi casi, prendere in considerazione fattori quali la frequenza delle query rispetto a tale tabella. Considerare anche se vale la pena mantenere i dati per quella tabella nel pool di buffer.

La cache di query evita di dover rieseguire una query quando si invia una query identica e i dati di tabella sottostante non vengono modificati. Le query ottimizzate mediante la funzionalità di query in parallelo possono essere memorizzate nella cache di query, in modo da generare risultati istantanei all'esecuzione successiva.

Nota

Quando si comparano le prestazioni, la cache di query può generare valori di durata artificialmente bassi. Di conseguenza, nelle comparazioni puoi utilizzare l'hint sql_no_cache. Questo hint impedisce la generazione dei risultati a partire dalla cache di query, anche se la stessa query è stata eseguita in precedenza. L'hint è posizionato subito dopo l'istruzione SELECT in una query. Molti esempi di query in parallelo in questo argomento includono questo suggerimento per consentire la comparazione, in termini di durata, delle versioni della stessa query con e senza la funzionalità di query in parallelo abilitata.

Assicurati di rimuovere questo hint dal codice sorgente quando utilizzi la funzionalità di query in parallelo in un ambiente di produzione.

Suggerimenti per l'ottimizzazione

Un altro modo per controllare l'ottimizzazione consiste nell'utilizzare i suggerimenti che possono essere specificati in singole istruzioni. Ad esempio, è possibile attivare l'ottimizzazione per una tabella in un'istruzione e quindi disattivare l'ottimizzazione per un'altra tabella. Per ulteriori informazioni su questi suggerimenti, consulta Optimizer Hints nel My Reference Manual. SQL

Puoi usare i SQL suggerimenti con Aurora Le SQL mie query per ottimizzare le prestazioni. È inoltre possibile utilizzare i suggerimenti per impedire che i piani di esecuzione per query importanti vengano modificati a causa di condizioni imprevedibili.

Abbiamo esteso la funzionalità dei SQL suggerimenti per aiutarti a controllare le scelte degli ottimizzatori per i tuoi piani di query. Questi suggerimenti si applicano alle query che utilizzano l'ottimizzazione delle query parallele. Per ulteriori informazioni, consulta Aurora I miei suggerimenti SQL.

Le mie tabelle temporanee ISAM

L'ottimizzazione mediante query in parallelo è applicabile solo alle tabelle InnoDB. Poiché Aurora My SQL utilizza My ISAM dietro le quinte per le tabelle temporanee, le fasi di interrogazione interne che coinvolgono tabelle temporanee non utilizzano mai la query parallela. Queste fasi di query sono indicate da Using temporary nell'output EXPLAIN.