Durata di una query Spanner

Client

Spanner supporta le query SQL. Ecco un esempio di query:

SELECT s.SingerId, s.FirstName, s.LastName, s.SingerInfo
FROM Singers AS s
WHERE s.FirstName = @firstName;

Il costrutto @firstName è un riferimento a un parametro di query. Puoi utilizzare uno dei seguenti parametro di query ovunque sia possibile usare un valore letterale. L'utilizzo dei parametri in le API per la pubblicità programmatica sono vivamente consigliate. L'uso dei parametri di ricerca consente di evitare Gli attacchi di iniezione SQL e le query risultanti sono più probabili per sfruttare le varie cache lato server. Consulta la sezione Memorizzazione nella cache di seguito.

I parametri di query devono essere associati a un valore durante l'esecuzione della query. Per esempio:

Statement statement =
    Statement.newBuilder("SELECT s.SingerId...").bind("firstName").to("Jimi").build();
try (ResultSet resultSet = dbClient.singleUse().executeQuery(statement)) {
 while (resultSet.next()) {
 ...
 }
}

Quando Spanner riceve una chiamata API, analizza la query e per determinare quale nodo server Spanner deve elaborare query. Il server restituisce un flusso di righe di risultati utilizzate dal chiamate a ResultSet.next().

Esecuzione della query

L'esecuzione della query inizia con l'arrivo di una "query di esecuzione" una richiesta Spanner. Il server esegue questi passaggi:

  • Convalida la richiesta
  • Analizza il testo della query
  • Generare un'algebra di query iniziale
  • Genera un'algebra delle query ottimizzata
  • Genera un piano di query eseguibile
  • Eseguire il piano (controllare le autorizzazioni, leggere i dati, codificare i risultati e così via)

Diagramma di flusso relativo all'esecuzione della query che mostra client, server radice e server foglia

Analisi in corso...

Il parser SQL analizza il testo della query e lo converte in una sintassi astratta ad albero. Estrae la struttura di query di base (SELECT … FROM … WHERE …) ed esegue i controlli sintattici.

Algebra

Il sistema di tipo di Spanner può rappresentare scalari, array strutture e così via. L'algebra delle query definisce gli operatori per le scansioni delle tabelle, i filtri, ordinamento/raggruppamento, ogni tipo di join, aggregazione e molto altro ancora. L'iniziale l'algebra delle query viene creata dall'output del parser. Riferimenti nomi campo in vengono risolte usando lo schema del database. Questo codice verifica anche errori semantici (ad es. numero errato di parametri, errori di corrispondenza del tipo e così via) ).

Il passaggio successivo ("ottimizzazione della query") prende l'algebra iniziale e genera una un'algebra più ottimale. Potrebbe essere più semplice, più efficiente o semplicemente più adatto alle capacità del motore di esecuzione. Ad esempio, l'algebra iniziale potrebbe specificare solo un "join" mentre l'algebra ottimizzata specifica un "hash join".

Esecuzione

Il piano di query eseguibile finale viene creato a partire dall'algebra riscritta. In pratica, il piano eseguibile è un grafico diretto aciclico di "iteratori". Ogni iteratore espone una sequenza di valori. Gli iteratori possono consumare per produrre output (ad esempio, ordinamento iteratore). Query che coinvolgono un solo split può essere eseguito da un singolo server (quello che contiene i dati). Il server analizzerà intervalli da varie tabelle, eseguirà join, l'aggregazione e tutte le altre operazioni definite dall'algebra delle query.

Le query che prevedono più suddivisioni verranno suddivise in più parti. Alcune parte della query continuerà a essere eseguita sul server principale (root). Altro vengono trasferite ai nodi foglia (quelli che possiedono le suddivisioni che lettura). Questo passaggio può essere applicato in modo ricorsivo a query complesse, in una struttura di esecuzioni del server. Tutti i server concordano su un timestamp in modo che i risultati della query sono un'istantanea coerente dei dati. Ogni server foglia restituisce un flusso di risultati parziali. Per le query che prevedono l'aggregazione, potrebbero essere di risultati parzialmente aggregati. Il server radice delle query elabora i risultati i server foglia ed esegue il resto del piano di query. Per ulteriori informazioni, vedi Piani di esecuzione delle query.

Quando una query prevede più suddivisioni, Spanner può eseguirla in in parallelo tra le suddivisioni. Il grado di parallelismo dipende l'intervallo di dati analizzati dalla query, il piano di esecuzione della query e la distribuzione dei dati tra le suddivisioni. Spanner imposta automaticamente il grado massimo di parallelismo per un in base alle dimensioni dell'istanza e alla configurazione dell'istanza (una o più regioni) al fine di ottenere prestazioni delle query ottimali e evitare di sovraccaricare la CPU.

Memorizzazione nella cache

Molti degli artefatti dell'elaborazione delle query vengono automaticamente memorizzati nella cache e riutilizzati per le query successive. Sono inclusi algebra delle query, piani di query eseguibili, e così via. La memorizzazione nella cache si basa sul testo della query, sui nomi e sui tipi di parametri e così via. Ecco perché utilizzare parametri associati (come @firstName in nell'esempio precedente) è meglio che utilizzare valori letterali nel testo della query. La le prime possono essere memorizzate nella cache una volta e riutilizzate a prescindere dall'effettivo valore associato. Consulta Ottimizzazione delle prestazioni delle query di Spanner per ulteriori dettagli.

Gestione degli errori

Il flusso di righe di risultati dal metodo executeQuery può essere interrotto per motivi diversi: errori di rete temporanei, trasferimento di una suddivisione da un server all'altro (ad es. bilanciamento del carico), riavvii del server (ad es. eseguire l'upgrade a una nuova versione) e così via. Per risolvere più facilmente questi errori, Spanner invia "token di ripresa" opachi insieme a batch di parti e i dati dei risultati. Questi token di ripristino possono essere utilizzati quando si ripete la query per continuare dal punto in cui era stata interrotta la query. Se usi Spanner librerie client, questa operazione viene eseguita automaticamente; perciò gli utenti della libreria client non devi preoccuparti di questo tipo di errore temporaneo.