Questa pagina descrive come eseguire letture in Spanner al di fuori del contesto delle transazioni di sola lettura e di lettura/scrittura. Se si verifica una delle seguenti condizioni, devi leggere la pagina Transazioni:
Se devi scrivere, a seconda del valore di una o più letture, devi eseguire la lettura nell'ambito di una transazione di lettura/scrittura. Per ulteriori informazioni, consulta la sezione sulle transazioni di lettura/scrittura.
Se effettui più chiamate di lettura che richiedono una visione coerente dei tuoi dati, devi eseguire le letture nell'ambito di una transazione di sola lettura. Per ulteriori informazioni, consulta la sezione sulle transazioni di sola lettura.
Tipi di lettura
Spanner ti consente di determinare quanto aggiornati devono essere i dati quando li leggi offrendo due tipi di letture:
- Una lettura affidabile è una lettura con un timestamp corrente e garantisce di vedere tutti i dati di cui è stato eseguito il commit fino all'inizio di questa lettura. Per impostazione predefinita, Spanner utilizza letture sicure per soddisfare le richieste di lettura.
- Una lettura non aggiornata viene letta in base a un timestamp passato. Se la tua applicazione è sensibile alla latenza, ma tollera i dati non aggiornati, le letture non aggiornate possono offrire vantaggi in termini di prestazioni.
Per scegliere il tipo di lettura che preferisci, imposta un limite di timestamp sulla richiesta di lettura. Segui queste best practice per scegliere un intervallo di timestamp:
Scegli letture sicure, se possibile. Questi sono i limiti di timestamp predefiniti per le letture di Spanner, incluse le transazioni di sola lettura. Le letture sicure garantiscono di osservare gli effetti di tutte le transazioni committate prima dell'inizio dell'operazione, indipendentemente dalla replica che riceve la lettura. Per questo motivo, le letture sicure semplificano il codice dell'applicazione e rendono le applicazioni più affidabili. Scopri di più sulle proprietà di coerenza di Spanner in TrueTime e coerenza esterna.
Se la latenza rende impraticabili le letture sicure in alcune situazioni, utilizza le letture non aggiornate (con latenza limitata o esatta) per migliorare le prestazioni nei punti in cui non è necessario che le letture siano il più recenti possibile. Come descritto nella pagina Riproduzione, 15 secondi è un valore di inattività ragionevole da utilizzare per un buon rendimento.
Leggere i dati con un ruolo database
Se sei un utente con controllo dell'accesso granulare, devi selezionare un ruolo del database per eseguire istruzioni e query SQL ed eseguire operazioni sulle righe di un database. La selezione del ruolo persiste per tutta la sessione fino a quando non modifichi il ruolo.
Per istruzioni su come eseguire una lettura con un ruolo del database, consulta Accedere a un database con controllo dell'accesso granulare.
Metodi di lettura singola
Spanner supporta metodi di lettura singola (ovvero una lettura al di fuori del contesto di una transazione) su un database per:
- Esegui la lettura come istruzione di query SQL o utilizza l'API di lettura di Spanner.
- Eseguire una lettura sicura da una singola riga o da più righe in una tabella.
- Esecuzione di una lettura non aggiornata da una singola riga o da più righe in una tabella.
- Lettura da una singola riga o da più righe in un indice secondario.
Se vuoi indirizzare singole letture a una replica o a una regione specifica all'interno di una configurazione di istanze multi-regione o di una configurazione regionale personalizzata con regioni facoltative di sola lettura, consulta Letture dirette.
Le sezioni seguenti descrivono come utilizzare i metodi di lettura con le librerie client Spanner.
Esegui una query
Di seguito viene mostrato come eseguire un'istruzione di query SQL su un database.
GoogleSQL
C++
Utilizza ExecuteQuery()
per eseguire un'istruzione di query SQL su un database.
C#
Utilizza ExecuteReaderAsync()
per eseguire query sul database.
Vai
Utilizza Client.Single().Query
per eseguire query sul database.
Java
Utilizza ReadContext.executeQuery
per eseguire query sul database.
Node.js
Utilizza Database.run
per eseguire query sul database.
PHP
Utilizza Database::execute
per eseguire query sul database.
Python
Utilizza Database.execute_sql
per eseguire query sul database.
Ruby
Utilizza Client#execute
per eseguire query sul database.
Consulta i riferimenti alla sintassi delle query e alle funzioni e agli operatori SQL quando costruisci un'istruzione SQL.
Eseguire una lettura efficace
Di seguito viene mostrato come eseguire una lettura sicura di zero o più righe da un database.
GoogleSQL
C++
Il codice per leggere i dati è lo stesso dell'esempio precedente per eseguire query su Spanner eseguendo una query SQL.
C#
Il codice per leggere i dati è lo stesso dell'esempio precedente per eseguire query su Spanner eseguendo una query SQL.
Vai
Utilizza Client.Single().Read
per leggere le righe dal database.
L'esempio utilizza AllKeys
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Java
Utilizza ReadContext.read
per leggere le righe dal database.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Node.js
Utilizza Table.read
per leggere le righe dal database.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
PHP
Utilizza Database::read
per leggere le righe dal database.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Python
Utilizza Database.read
per leggere le righe dal database.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Ruby
Utilizza Client#read
per leggere le righe dal database.
Eseguire una lettura obsoleta
Il seguente codice di esempio mostra come eseguire una lettura obsoleta di zero o più righe da un database utilizzando un limite di timestamp esatto. Per istruzioni su come eseguire una lettura non aggiornata utilizzando un limite di timestamp con tempo di aggiornamento limitato, consulta la nota dopo il codice di esempio. Per ulteriori informazioni sui diversi tipi di limiti di timestamp disponibili, consulta la sezione Limiti di timestamp.
GoogleSQL
C++
Utilizza ExecuteQuery()
con MakeReadOnlyTransaction()
e
Transaction::ReadOnlyOptions()
per eseguire una lettura non aggiornata.
C#
Utilizza il metodo BeginReadOnlyTransactionAsync
su un connection
con un valore TimestampBound.OfExactStaleness()
specificato per eseguire query sul database.
Vai
Utilizza Client.ReadOnlyTransaction().WithTimestampBound()
e specifica un valore ExactStaleness
per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di accuratezza dell'obsolescenza.
L'esempio utilizza AllKeys
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Java
Utilizza il metodo read
di un ReadContext
con un TimestampBound.ofExactStaleness()
specificato per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di accuratezza dell'obsolescenza.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Node.js
Utilizza Table.read
con l'opzione exactStaleness
per eseguire una lettura delle righe
dal database utilizzando un limite di timestamp di inattualità esatto.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
PHP
Utilizza Database::read
con un valore exactStaleness
specificato per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di inattività esatto.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Python
Utilizza il metodo read
di un Database
snapshot
con un valore exact_staleness
specificato per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di accuratezza dell'obsolescenza.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Ruby
Utilizza il metodo read
di uno snapshot Client
con un valore staleness
(in secondi) specificato per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di accuratezza della data.
Eseguire una lettura utilizzando un indice
Di seguito viene mostrato come leggere zero o più righe da un database utilizzando un indice:
GoogleSQL
C++
Utilizza la funzione Read()
per eseguire una lettura utilizzando un indice.
C#
Leggi i dati utilizzando l'indice eseguendo una query che specifica esplicitamente l'indice:
Vai
Utilizza Client.Single().ReadUsingIndex
per leggere le righe dal database utilizzando un indice.
Java
Utilizza ReadContext.readUsingIndex
per leggere le righe dal database utilizzando un indice.
Node.js
Utilizza Table.read
e specifica l'indice nella query per leggere le righe dal database utilizzando un indice.
PHP
Utilizza Database::read
e specifica l'indice per leggere le righe dal database
utilizzando un indice.
Python
Utilizza Database.read
e specifica l'indice per leggere le righe dal database
utilizzando un indice.
Ruby
Utilizza Client#read
e specifica l'indice per leggere le righe dal database utilizzando un indice.
Lettura di dati in parallelo
Quando esegui operazioni di lettura collettiva o query che richiedono quantità molto elevate di
dati di Spanner, puoi utilizzare l'API PartitionQuery
per ottenere risultati più rapidi. L'API suddivide la query in batch o
partizioni utilizzando più macchine per recuperare le partizioni in parallelo. Tieni conto che l'utilizzo dell'API PartitionQuery
comporta una maggiore latenza perché è pensata solo per operazioni collettive come l'esportazione o la scansione dell'intero database.
Puoi eseguire qualsiasi operazione dell'API di lettura in parallelo utilizzando le librerie client Spanner. Tuttavia, puoi partizionare le query SQL solo se sono partizionabili in base alla radice. Affinché una query sia partizionabile in base alla radice, il piano di query deve soddisfare una delle seguenti condizioni:
Il primo operatore nel piano di esecuzione della query è un'unione distribuita e il piano di esecuzione della query contiene una sola unione distribuita (esclusi gli operatori Local Distribution Union). Il piano di query non può contenere altri operatori distribuiti, ad esempio la applicazione tra insiemi distribuita.
Nel piano di query non sono presenti operatori distribuiti.
L'API PartitionQuery
esegue le query in modalità batch. Spanner potrebbe scegliere un piano di esecuzione delle query che renda le query partizionabili in base alla radice quando vengono eseguite in modalità batch. Di conseguenza, l'API PartitionQuery
e
Spanner Studio potrebbero utilizzare piani di esecuzione delle query diversi
per la stessa query. Potresti non riuscire a recuperare il piano di esecuzione delle query utilizzato dall'API PartitionQuery
su Spanner Studio.
Per query partizionate come questa, puoi scegliere di attivare Spanner Data Boost. Data Boost ti consente di eseguire query analitiche di grandi dimensioni con un impatto quasi nullo sui carichi di lavoro esistenti nell'istanza Spanner di cui è stato eseguito il provisioning. Gli esempi di codice C++, Go, Java, Node.js e Python in questa pagina mostrano come attivare il potenziamento dei dati.
Per saperne di più su Data Boost, consulta Panoramica di Data Boost.
GoogleSQL
C++
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di una transazione batch di Spanner.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
C#
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di una transazione batch di Spanner.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
Vai
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client Spanner e di una transazione.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
Java
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client batch Spanner e di una transazione.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
Node.js
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client Spanner e di un batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
PHP
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client Spanner e di un batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
Python
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client Spanner e di una transazione batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.
Ruby
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed
esegue la query su ogni partizione tramite i seguenti passaggi:
- Creazione di un client batch Spanner.
- Creazione di partizioni per la query, in modo che possano essere distribuite su più worker.
- Recupero dei risultati della query per ogni partizione.