Risolvere i problemi relativi alle regressioni delle prestazioni

Quando utilizzi query SQL per cercare dati, Spanner utilizza automaticamente qualsiasi indice secondario che potrebbe contribuire a recuperare i dati in modo più efficiente. Tuttavia, in alcuni casi, Spanner potrebbe scegliere un indice che rallenta le query. Di conseguenza, potresti notare che alcune query sono più lente di quanto non fossero eseguite in passato.

Questa pagina spiega come rilevare cambiamenti nella velocità di esecuzione delle query, ispezionare il piano di esecuzione delle query per queste query e specificare un indice diverso per le query future, se necessario.

Rileva le modifiche nella velocità di esecuzione delle query

Molto probabilmente noterai una variazione nella velocità di esecuzione delle query dopo aver apportato una di queste modifiche:

  • Modifica significativa di una grande quantità di dati esistenti con un indice secondario.
  • Aggiunta, modifica o eliminazione di un indice secondario.

Puoi utilizzare diversi strumenti per identificare una query specifica che Spanner viene eseguita più lentamente del solito:

Una nota sui nuovi database

Durante l'esecuzione di query su database appena creati con dati appena inseriti o importati, Spanner potrebbe non selezionare gli indici più appropriati, in quanto lo strumento di ottimizzazione delle query potrebbe impiegare fino a tre giorni per raccogliere automaticamente le statistiche di ottimizzazione. Per ottimizzare l'utilizzo dell'indice di un nuovo database Spanner prima di questa data, puoi creare manualmente un nuovo pacchetto di statistiche.

Esamina lo schema

Dopo aver trovato la query che ha rallentato, esamina l'istruzione SQL per la query e identifica le tabelle utilizzate dall'istruzione e le colonne recuperate da quelle tabelle.

Poi, trova gli indici secondari esistenti per queste tabelle. Determinare se uno degli indici include le colonne su cui stai eseguendo la query, il che significa che Spanner potrebbe utilizzare uno degli indici per elaborare la query.

  • Se sono presenti indici applicabili, il passaggio successivo è trovare l'indice utilizzato da Spanner per la query.
  • Se non sono presenti indici applicabili, utilizza il comando gcloud spanner operations list per verificare se di recente hai eliminato un indice applicabile:

    gcloud spanner operations list \
        --instance=INSTANCE \
        --database=DATABASE \
        --filter="@TYPE:UpdateDatabaseDdlMetadata"
    

    Se hai eliminato un indice applicabile, la modifica potrebbe aver influito sulle prestazioni delle query. Aggiungi di nuovo l'indice secondario alla tabella. Dopo che Spanner ha aggiunto l'indice, esegui di nuovo la query per controllarne le prestazioni. Se le prestazioni non migliorano, il passaggio successivo è trovare l'indice utilizzato da Spanner per la query.

    Se non hai eliminato un indice applicabile, la selezione dell'indice non ha causato la regressione delle prestazioni delle query. Cerca altre modifiche ai dati o ai pattern di utilizzo che potrebbero aver influito sulle prestazioni.

Trovare l'indice utilizzato per una query

Per scoprire quale indice sta utilizzando Spanner per elaborare una query, visualizza il piano di esecuzione delle query nella console Google Cloud:

  1. Vai alla pagina Istanze di Spanner nella console Google Cloud.

    Vai alla pagina Istanze

  2. Fai clic sul nome dell'istanza su cui vuoi eseguire la query.

  3. Nel riquadro a sinistra, fai clic sul database su cui vuoi eseguire la query, poi fai clic su Spanner Studio.

  4. Inserisci la query da verificare.

  5. Nell'elenco a discesa Esegui query, seleziona Solo spiegazione. Spanner mostra il piano di query.

Cerca almeno uno dei seguenti operatori nel piano di query:

  • Scansione della tabella
  • Scansione dell'indice
  • Applicazione incrociata o applicazione incrociata distribuita

Le seguenti sezioni spiegano il significato di ciascun operatore.

Operatore di scansione delle tabelle

L'operatore di scansione delle tabelle indica che Spanner non ha utilizzato un indice secondario:

Uno screenshot mostra un operatore di scansione delle tabelle in un piano di query.

Ad esempio, supponiamo che la tabella Albums non abbia indici secondari e che tu esegua la seguente query:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

Poiché non sono presenti indici da utilizzare, il piano di query include un operatore di scansione delle tabelle.

Operatore di scansione dell'indice

L'operatore di scansione dell'indice indica che Spanner ha utilizzato un indice secondario durante l'elaborazione della query:

Uno screenshot mostra un operatore di scansione dell'indice in un piano di query.

Ad esempio, supponi di aggiungere un indice alla tabella Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Quindi esegui la query seguente:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

L'indice AlbumsByAlbumTitle contiene AlbumTitle, che è l'unica colonna selezionata dalla query. Di conseguenza, il piano di query include un operatore di scansione dell'indice.

Operatore Applica incrociati

In alcuni casi, Spanner utilizza un indice che contiene solo alcune delle colonne selezionate dalla query. Di conseguenza, Spanner deve unire l'indice alla tabella di base.

Quando si verifica questo tipo di join, il piano di query include un operatore cross apply o Distributed Cross apply con i seguenti input:

  • Un operatore di scansione dell'indice per l'indice di una tabella
  • Un operatore di scansione della tabella proprietaria dell'indice

Uno screenshot mostra un'applicazione incrociata distribuita in un piano di query, con una scansione dell'indice e una tabella come input.

Ad esempio, supponi di aggiungere un indice alla tabella Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Quindi esegui la query seguente:

SELECT * FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

L'indice AlbumsByAlbumTitle contiene AlbumTitle, ma la query seleziona tutte le colonne della tabella, non solo AlbumTitle. Di conseguenza, il piano di query include un operatore di applicazione incrociata distribuita, con una scansione dell'indice di AlbumsByAlbumTitle e una scansione della tabella di Albums come input.

Scegli un indice diverso

Dopo aver trovato l'indice utilizzato da Spanner per la query, prova a eseguire la query con un indice diverso o a eseguire la scansione della tabella di base anziché utilizzare un indice. Per specificare l'indice, aggiungi un'istruzione FORCE_INDEX alla query.

Se trovi una versione più veloce della query, aggiorna l'applicazione per utilizzare la versione più rapida.

Linee guida per la scelta di un indice

Utilizza queste linee guida per decidere quale indice testare per la query:

  • Se la query soddisfa uno di questi criteri, prova a utilizzare la tabella di base anziché un indice secondario:

    • La query verifica la presenza dell'uguaglianza con un prefisso della chiave primaria della tabella di base (ad esempio, SELECT * FROM Albums WHERE SingerId = 1).
    • Un numero elevato di righe soddisfa i predicati della query (ad esempio, SELECT * FROM Albums WHERE AlbumTitle != "There Is No Album With This Title").
    • La query utilizza una tabella di base che contiene solo poche centinaia di righe.
  • Se la query contiene un predicato molto selettivo (ad esempio REGEXP_CONTAINS, STARTS_WITH, <, <=, >, >= o !=), prova a utilizzare un indice che includa le stesse colonne che utilizzi nel predicato.

Testa la query aggiornata

Utilizza la console Google Cloud per testare la query aggiornata e scoprire quanto tempo richiede per elaborarla.

Se la tua query include parametri di query e un parametro di query è associato ad alcuni valori molto più spesso di altri, associa il parametro di query a uno di questi valori nei tuoi test. Ad esempio, se la query include un predicato come WHERE country = @countryId e quasi tutte le query associano @countryId al valore US, associa @countryId a US per i test delle prestazioni. Questo approccio ti aiuta a ottimizzare per le query che esegui più di frequente.

Per testare la query aggiornata nella console Google Cloud, segui questi passaggi:

  1. Vai alla pagina Istanze di Spanner nella console Google Cloud.

    Vai alla pagina Istanze

  2. Fai clic sul nome dell'istanza su cui vuoi eseguire la query.

  3. Nel riquadro a sinistra, fai clic sul database su cui vuoi eseguire la query, poi fai clic su Spanner Studio.

  4. Inserisci la query da verificare, inclusa l'istruzione FORCE_INDEX, e fai clic su Esegui query.

    Nella console Google Cloud viene aperta la scheda Tabella dei risultati, quindi vengono visualizzati i risultati della query, incluso il tempo impiegato dal servizio Spanner per elaborare la query.

    Questa metrica non include altre fonti di latenza, ad esempio il tempo impiegato dalla console Google Cloud per interpretare e visualizzare i risultati delle query.

Ottieni il profilo dettagliato di una query in formato JSON utilizzando l'API REST

Per impostazione predefinita, quando esegui una query vengono restituiti solo i risultati delle istruzioni. Questo perché QueryMode è impostato su NORMAL. Per includere statistiche di esecuzione dettagliate nei risultati della query, imposta QueryMode su PROFILE.

Creare una sessione

Prima di aggiornare la modalità query, crea una sessione, che rappresenta un canale di comunicazione con il servizio di database Spanner.

  1. Fai clic su projects.instances.databases.sessions.create.
  2. Fornisci l'ID progetto, istanza e database nel seguente modulo:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]
    
  3. Fai clic su Execute (Esegui). La risposta mostra la sessione che hai creato in questo modulo:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]/sessions/[\SESSION\]
    

    Lo utilizzerai per eseguire il profilo di query nel passaggio successivo. La sessione creata sarà attiva per un massimo di un'ora tra utilizzi consecutivi prima di essere eliminata dal database.

Profila la query

Attiva la modalità PROFILE per la query.

  1. Fai clic su projects.instances.databases.sessions.executeSql.
  2. Per sessione, inserisci l'ID sessione creato nel passaggio precedente:

    projects/[PROJECT_ID]/instances/[INSTANCE_ID]/databases/[DATABASE_ID]/sessions/[SESSION]
    
  3. Per Corpo della richiesta, utilizza quanto segue:

    {
      "sql": "[YOUR_SQL_QUERY]",
      "queryMode": "PROFILE"
    }
    
  4. Fai clic su Execute (Esegui). La risposta restituita includerà i risultati della query, il piano di query e le statistiche di esecuzione della query.