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à.
Ottimizza le interrogazioni
Attieniti alle tecniche di ottimizzazione delle query descritte in questa sezione per velocizzare l'esecuzione delle query o per rimediare al problema delle query che superano i limiti di risorse in Athena.
Ottimizza i join
Le strategie per eseguire join in un motore di query distribuito sono svariate. Due delle più comuni sono gli hash join distribuiti e le query con condizioni di join complesse.
In un hash join distribuito, posiziona le tabelle grandi a sinistra e le tabelle piccole a destra
Il tipo più comune di join utilizza come condizione di join un confronto di uguaglianza. Athena esegue questo tipo di join come hash join distribuito.
In un hash join distribuito, il motore crea una tabella di ricerca (tabella hash) da uno dei lati del join. Questo lato è denominato il lato build. I record del lato build sono distribuiti tra i nodi. Ogni nodo costruisce una tabella di ricerca per il relativo sottoinsieme. L'altro lato del join, denominato lato probe, è quindi trasmesso in streaming attraverso i nodi. I record dal lato probe sono distribuiti sui nodi nello stesso modo del lato build. Ciò consente a ciascun nodo di eseguire il join cercando i record corrispondenti nella relativa tabella di ricerca.
Quando le tabelle di ricerca create dal lato build del join non rientrano nella memoria, le query possono non andare a buon fine. Anche se la dimensione totale del lato di build è inferiore alla memoria disponibile, se la distribuzione dei record presenta un'asimmetria significativa, le query possono comunque avere esito negativo. In un caso estremo, è possibile che tutti i record abbiano per la condizione di join lo stesso valore e che sia richiesto che vengano immessi nella memoria su un singolo nodo. Anche una query con asimmetria minore può avere esito negativo se un set di valori viene inviato allo stesso nodo e la somma dei valori supera la quantità superiore di memoria disponibile. I nodi hanno la capacità di versare i record su disco, tuttavia il versamento rallenta l'esecuzione delle query e può essere insufficiente per evitare che la query abbia esito negativo.
Athena tenta di riordinare i join per utilizzare la relazione più grande come lato probe e la relazione più piccola come lato build. Tuttavia Athena, poiché non gestisce i dati nelle tabelle, dispone di informazioni limitate e spesso deve presumere che la prima tabella sia la più grande e la seconda tabella sia la più piccola.
Quando scrivi join con condizioni di join basate sull'uguaglianza, presumi che la tabella a sinistra della parola chiave JOIN
sia il lato probe e la tabella a destra sia il lato build. Assicurati che la tabella a destra, il lato build, sia la tabella di dimensioni inferiori. Se non è possibile ridurre le dimensione del lato build del join affinché rientri nella memoria, considera la possibile di eseguire più query che uniscano sottoinsiemi della tabella build.
EXPLAINUtilizzatelo per analizzare le interrogazioni con join complessi
Le query con condizioni di join complesse (ad esempio, query che utilizzano LIKE
o altri operatori) sono spesso impegnative dal punto di vista computazionale. >
Nel peggiore dei casi, tutti i record di un lato del join devono essere confrontati con tutti i record sull'altro lato del join. Poiché il tempo di esecuzione aumenta con il quadrato del numero di record, si rischia che tali query superino il tempo di esecuzione massimo.
Per sapere in in anticipo in che modo Athena eseguirà la query, puoi utilizzare la dichiarazione EXPLAIN
. Per ulteriori informazioni, consulta Utilizzo di EXPLAIN e EXPLAIN ANALYZE in Athena e Comprendi i risultati della dichiarazione di Athena EXPLAIN.
Riduci l'ambito delle funzioni delle finestre o rimuovile
Le funzioni delle finestre, poiché richiedono molte risorse, possono rallentare o addirittura far fallire le query con il messaggio La query ha esaurito le risorse con questo fattore di scala
. Le funzioni finestra conservano in memoria tutti i record su cui operano per calcolarne il risultato. Quando la finestra è di dimensioni molto grandi, la funzione finestra può esaurire la memoria.
Per assicurarti che le query vengano eseguite entro i limiti di memoria disponibili, riduci le dimensioni delle finestre su cui operano le funzioni finestra. A tale scopo, puoi aggiungere una clausola PARTITIONED BY
o restringere l'ambito delle clausole di partizionamento esistenti.
Usa funzioni diverse dalla finestra
A volte le query con le funzioni finestra possono essere riscritte senza funzioni finestra. Ad esempio, invece di utilizzare row_number
per trovare i record top N
, puoi utilizzare ORDER BY
e LIMIT
. Anziché utilizzare row_number
o rank
per deduplicare i record, puoi utilizzare funzioni aggregate come max_by
Ad esempio, considera di disporre di un set di dati con aggiornamenti da un sensore. Il sensore comunica regolarmente lo stato della batteria e include alcuni metadati quali la posizione. Se vuoi conoscere lo stato più recente della batteria di ogni sensore e la sua posizione, puoi utilizzare questa query:
SELECT sensor_id, arbitrary(location) AS location, max_by(battery_status, updated_at) AS battery_status FROM sensor_readings GROUP BY sensor_id
Poiché i metadati, ad esempio la posizione, sono gli stessi per ogni record, puoi utilizzare la funzione arbitrary
per selezionare qualsiasi valore dal gruppo.
Per conoscere lo stato più recente della batteria, puoi usare la funzione max_by
. La funzione max_by
seleziona il valore di una colonna dal record in cui è stato trovato il valore massimo di un'altra colonna. In questo caso, la funzione restituisce lo stato della batteria del record con l'orario dell'ultimo aggiornamento all'interno del gruppo. Questa query viene eseguita più velocemente e utilizza meno memoria rispetto a una query equivalente con una funzione finestra.
Ottimizza le aggregazioni
Athena, quando esegue un'aggregazione, distribuisce i record tra i nodi worker utilizzando le colonne nella clausola GROUP BY
. Per rendere il più efficiente possibile l'abbinamento dei record ai gruppi, i nodi cercano di conservare i record in memoria ma, se necessario, li trasferiscono su disco.
Inoltre, nelle clausole GROUP
BY
è consigliabile evitare di includere colonne ridondanti. Poiché un numero inferiore di colonne richiede una quantità di memoria inferiore, è più efficiente una query che descrive un gruppo con un numero inferiore di colonne. Le colonne numeriche utilizzano inoltre una quantità di memoria inferiore rispetto alle stringhe. Ad esempio, quando aggreghi un set di dati che ha sia un ID di categoria numerico sia un nome di categoria, nella clausola GROUP BY
utilizza solo la colonna ID di categoria.
A volte le query includono colonne nella clausola GROUP BY
per ovviare al fatto che una colonna debba far parte della clausola GROUP BY
o di un'espressione aggregata. Se questa regola non viene seguita, puoi ricevere un messaggio di errore come il seguente:
EXPRESSION_ NOT _AGGREGATE: riga 1:8: 'category' deve essere un'espressione aggregata o apparire nella clausola BY GROUP
Per evitare di dover aggiungere colonne ridondanti alla GROUP BY
clausola, puoi utilizzare la funzione arbitraria
SELECT country_id, arbitrary(country_name) AS country_name, COUNT(*) AS city_count FROM world_cities GROUP BY country_id
La funzione ARBITRARY
restituisce un valore arbitrario dal gruppo. La funzione è utile quando sai che tutti i record del gruppo hanno lo stesso valore per una colonna, ma il valore non identifica il gruppo.
Ottimizza le prime N query
La clausola ORDER BY
restituisce i risultati di una query disponendoli in ordine. Athena utilizza l'ordinamento distribuito per eseguire l'operazione di ordinamento in parallelo su più nodi.
Se non è strettamente necessario ordinare i risultati, evita di aggiungere una clausola ORDER
BY
. Inoltre, se non sono strettamente necessarie, evita di aggiungere informazioni ORDER BY
alle query interne. In molti casi, il pianificatore di query può rimuovere l'ordinamento ridondante, ma ciò non è garantito. Un'eccezione a questa regola è prevista se una query interna esegue un'operazione top N
, ad esempio la ricerca dei valori N
più recenti o dei valori N
più comuni.
Athena, quando vede ORDER BY
insieme a LIMIT
, capisce che stai eseguendo una query top N
e mette in atto operazioni dedicate di conseguenza.
Nota
Sebbene Athena sia spesso in grado di rilevare anche funzioni finestra come row_number
che utilizza top N
, è consigliabile la versione più semplice che utilizza ORDER BY
e LIMIT
. Per ulteriori informazioni, consulta Riduci l'ambito delle funzioni delle finestre o rimuovile.
Come includere solo le colonne obbligatorie
Se una colonna non è strettamente necessaria, non includerla nella tua query. Minore è la quantità di dati che una query deve elaborare, maggiore sarà la velocità di esecuzione. Ciò riduce sia la quantità di memoria richiesta sia la quantità di dati da inviare tra i nodi. Se utilizzi un formato di file colonnare, la riduzione del numero di colonne fa comporta una diminuzione anche della quantità di dati letti da Amazon S3.
In Athena non sono previsti limiti specifici al numero di colonne in un risultato, tuttavia le modalità di esecuzione delle query limita la possibile dimensione combinata delle colonne. La dimensione combinata delle colonne include i relativi nomi e tipi.
Ad esempio, l'errore seguente è causato da una relazione che supera il limite di dimensione di un descrittore di relazione:
GENERIC_ INTERNAL _ERROR: io.airlift.bytecode. CompilationException
Per risolvere il problema, riduci il numero di colonne nella query o crea sottoquery e utilizza JOIN
che recuperi una quantità inferiore di dati. Se hai query che eseguono SELECT *
nella query più esterna, dovresti cambiare il *
a un elenco che presenti solo le colonne di cui hai bisogno.
Ottimizza le interrogazioni utilizzando approssimazioni
Athena supporta funzioni di aggregazione di approssimazione
A differenza delle operazioni COUNT(DISTINCT col)
, approx_distinct
Ottimizzazione di LIKE
Puoi usare LIKE
per trovare stringhe corrispondenti, ma per le stringhe lunghe richiede molto calcolo. La funzione regexp_like
Spesso puoi ottimizzare una ricerca ancorando la sottostringa che stai cercando. Ad esempio, se stai cercando un prefisso, è molto meglio usare 'substr
%' invece di '% %'. substr
Oppure, se stai usandoregexp_like
, '^ '. substr
Usa UNION ALL invece di UNION
UNION ALL
e UNION
sono due modi di combinare i risultati di due query in un unico risultato. UNION ALL
concatena i record della prima query con la seconda e UNION
fa lo stesso, ma rimuove anche i duplicati. UNION
deve elaborare tutti i record e trovare i duplicati, il che richiede molta memoria e calcolo, ma UNION ALL
è un'operazione relativamente rapida. A meno che non sia necessario deduplicare i record, utilizza UNION
ALL
per ottenere prestazioni ottimali.
Utilizzare UNLOAD per set di risultati di grandi dimensioni
Quando si prevede che i risultati di una query siano di grandi dimensioni (ad esempio, decine di migliaia di righe o più), utilizza UNLOAD per esportare i risultati. Nella maggior parte dei casi, questa operazione è più veloce rispetto all'esecuzione di una normale query e l'utilizzo di UNLOAD
offre anche maggior controllo sull'output.
Al termine dell'esecuzione di una query, Athena archivia il risultato come un singolo file non compresso CSV su Amazon S3. Questa operazione richiede più tempo di UNLOAD
, non solo perché il risultato non è compresso, ma anche perché l'operazione non può essere parallelizzata. Al contrario, UNLOAD
scrive i risultati direttamente dai nodi worker e utilizza appieno il parallelismo del cluster di elaborazione. Inoltre, puoi configurare UNLOAD
la scrittura dei risultati in formato compresso e in altri formati di file come Parquet. JSON
Per ulteriori informazioni, consulta UNLOAD.
Usa CTAS or Glue ETL per materializzare le aggregazioni utilizzate di frequente
La "materializzazione" di una query è un modo per accelerare le prestazioni delle query archiviando i risultati di query complesse precalcolate (ad esempio aggregazioni e join) per riutilizzarli nelle query successive.
Se molte delle query includono gli stessi join e le stesse aggregazioni, puoi materializzare la sottoquery comune come una nuova tabella e quindi eseguire query su quella tabella. Puoi creare la nuova tabella con Crea una tabella dai risultati della query (CTAS) o uno ETL strumento dedicato come Glue ETL
Ad esempio, considera di avere una dashboard con widget che mostrano diversi aspetti di un set di dati di ordini. Ogni widget ha una propria query, ma tutte queste condividono gli stessi join e filtri. Una tabella di ordini viene unita a una tabella di elementi, inoltre è presente un filtro per mostrare solo gli ultimi tre mesi. Se identifichi le funzionalità comuni di queste query, puoi creare una nuova tabella utilizzabile dai widget. Ciò riduce la duplicazione e migliora le prestazioni. Lo svantaggio è che devi mantenere aggiornata la nuova tabella.
Riutilizzo dei risultati query
Accade spesso che la stessa query venga eseguita più volte in un breve periodo. Ad esempio, ciò può succedere quando più persone aprono la stessa dashboard di dati. Quando esegui una query, puoi fare in modo che Athena riutilizzi i risultati calcolati in precedenza. Specifica l'età massima dei risultati da riutilizzare. Se la stessa query è stata eseguita in precedenza entro tale intervallo di tempo, Athena restituisce tali risultati anziché eseguire nuovamente la query. Per ulteriori informazioni, consulta Riutilizza i risultati della query in Athena nella Guida per l'utente di Amazon Athena e il blog Riduci i costi e migliora le prestazioni delle query con Amazon Athena Query Result Reuse