Questa pagina descrive come eseguire letture in Spanner al di fuori del contesto delle transazioni di sola lettura e lettura-scrittura. Se si applica una delle seguenti condizioni, dovresti leggere la pagina Transazioni:
Se devi scrivere, a seconda del valore di una o più letture, devi eseguire la lettura come parte di una transazione di lettura-scrittura. Per ulteriori informazioni, consulta le transazioni di lettura/scrittura.
Se stai effettuando più chiamate di lettura che richiedono una visualizzazione coerente dei tuoi dati, devi eseguire le letture come parte di una transazione di sola lettura. Per maggiori informazioni, consulta Transazioni di sola lettura.
Tipi di lettura
Spanner ti consente di determinare il grado di attualità dei dati quando leggi i dati, offrendo due tipi di lettura:
- Una lettura efficace è una lettura in corrispondenza di un timestamp attuale ed è garantita per visualizzare tutti i dati di cui è stato eseguito il commit fino all'inizio della lettura. Per impostazione predefinita, Spanner utilizza letture efficaci per gestire le richieste di lettura.
- Una lettura inattiva viene letta a un timestamp passato. Se la tua applicazione è sensibile alla latenza, ma tollera i dati inattivi, le letture obsolete possono offrire vantaggi in termini di prestazioni.
Per scegliere il tipo di lettura, imposta un limite a un timestamp nella richiesta di lettura. Utilizza le seguenti best practice quando scegli un timestamp associato:
Scegli letture efficaci ogni volta che è possibile. Questi sono i timestamp predefiniti per le letture di Spanner, incluse le transazioni di sola lettura. È garantito che le letture efficaci osservino gli effetti di tutte le transazioni sottoposte a commit prima dell'inizio dell'operazione, indipendentemente da quale replica riceve la lettura. Per questo motivo, le letture efficaci rendono il codice più semplice e le applicazioni più affidabili. Scopri di più sulle proprietà di coerenza di Spanner in TrueTime e coerenza esterna.
Se la latenza rende irrealizzabili le letture forti in alcune situazioni, usa i lettori inattivi (incertezza limitata o obsolescenza esatta) per migliorare le prestazioni nei luoghi in cui non è necessario che le letture siano il più recenti possibile. Come descritto nella pagina Replica, 15 secondi è un valore di inattività ragionevole da utilizzare per prestazioni ottimali.
Lettura di dati con un ruolo di database
Se sei un utente del controllo dell'accesso granulare, devi selezionare un ruolo del database per eseguire istruzioni e query SQL ed eseguire operazioni sulle righe su un database. La selezione del ruolo persiste per tutta la sessione fino a quando non lo cambi.
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 singoli
Spanner supporta metodi di lettura singoli (ovvero una lettura al di fuori del contesto di una transazione) su un database per:
- Esecuzione della lettura come istruzione di query SQL o utilizzo dell'API di lettura di Spanner.
- Esecuzione di una lettura efficace da una singola riga o da più righe di una tabella.
- Esecuzione di una lettura inattiva da una singola riga o da più righe di una tabella.
- Lettura da una o più righe di un indice secondario.
Se vuoi instradare singole letture su una specifica replica o regione all'interno di una configurazione di istanze multiregionali o di una configurazione regionale personalizzata con regioni facoltative di sola lettura, consulta Letture indirizzate.
Le seguenti sezioni descrivono come utilizzare i metodi di lettura con le librerie client di Spanner.
Esegui una query
Di seguito viene mostrato come eseguire un'istruzione di query SQL su un database.
GoogleSQL
C++
Usa ExecuteQuery()
per eseguire un'istruzione di query SQL su un database.
C#
Usa ExecuteReaderAsync()
per eseguire query sul database.
Go
Usa Client.Single().Query
per eseguire query sul database.
Java
Usa ReadContext.executeQuery
per eseguire query sul database.
Node.js
Usa Database.run
per eseguire query sul database.
PHP
Usa Database::execute
per eseguire query sul database.
Python
Usa Database.execute_sql
per eseguire query sul database.
Ruby
Usa Client#execute
per eseguire query sul database.
Consulta i riferimenti alla sintassi delle query e a funzioni e operatori SQL durante la creazione di un'istruzione SQL.
Esegui una lettura efficace
Di seguito viene mostrato come eseguire una lettura efficace 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 mediante esecuzione di una query SQL.
C#
Il codice per leggere i dati è lo stesso dell'esempio precedente per eseguire query su Spanner mediante esecuzione di una query SQL.
Go
Usa Client.Single().Read
per leggere le righe del database.
L'esempio utilizza AllKeys
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Java
Usa ReadContext.read
per leggere le righe del database.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Node.js
Usa Table.read
per leggere le righe del database.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
PHP
Usa Database::read
per leggere le righe del database.
L'esempio utilizza keySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Python
Usa Database.read
per leggere le righe del database.
L'esempio utilizza KeySet
per definire una raccolta di chiavi o intervalli di chiavi da leggere.
Ruby
Usa Client#read
per leggere le righe del database.
Eseguire una lettura obsoleta
Il seguente codice campione mostra come eseguire una lettura inattiva di zero o più righe da un database utilizzando un timestamp di inattività esatta vincolato. Per istruzioni su come eseguire una lettura inattiva utilizzando un timestamp di inattività limitata vincolato, vedi la nota dopo il codice campione. Consulta la sezione Limiti del timestamp per ulteriori informazioni sui diversi tipi di limiti del timestamp disponibili.
GoogleSQL
C++
Usa ExecuteQuery()
con MakeReadOnlyTransaction()
e
Transaction::ReadOnlyOptions()
per eseguire una lettura obsoleta.
C#
Utilizza il metodo BeginReadOnlyTransactionAsync
su un connection
con un
valore TimestampBound.OfExactStaleness()
specificato per eseguire query sul database.
Go
Utilizza Client.ReadOnlyTransaction().WithTimestampBound()
e specifica un
valore ExactStaleness
per eseguire una lettura delle righe del database utilizzando un
limite di timestamp di inattività esatto.
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 valore TimestampBound.ofExactStaleness()
specificato per eseguire una lettura di righe dal database utilizzando un timestamp di inattività esatto associato.
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 del database utilizzando un timestamp di inattività esatto associato.
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 di righe del database utilizzando un limite di timestamp di inattività esatta.
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 di righe dal database utilizzando un timestamp di inattività esatto associato.
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
specificato (in secondi) per eseguire una lettura di righe dal database utilizzando un timestamp di inattività esatto associato.
Esecuzione di una lettura utilizzando un indice
Di seguito viene mostrato come leggere zero o più righe di 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 in modo esplicito l'indice:
Go
Utilizza Client.Single().ReadUsingIndex
per leggere le righe del database utilizzando un indice.
Java
Utilizza ReadContext.readUsingIndex
per leggere le righe del database utilizzando un indice.
Node.js
Utilizza Table.read
e specifica l'indice nella query per leggere le righe del database utilizzando un indice.
PHP
Utilizza Database::read
e specifica l'indice per leggere le righe del database utilizzando un indice.
Python
Utilizza Database.read
e specifica l'indice per leggere le righe del database utilizzando un indice.
Ruby
Utilizza Client#read
e specifica l'indice per leggere le righe del database utilizzando un indice.
Lettura di dati in parallelo
Quando esegui operazioni di lettura o query collettive che coinvolgono quantità molto elevate di dati da Spanner, puoi utilizzare l'API PartitionQuery
per ottenere risultati più rapidi. L'API divide la query in batch, o partizioni, utilizzando più macchine per recuperare le partizioni in parallelo. Tieni presente che l'utilizzo dell'API PartitionQuery
causa una latenza maggiore in quanto è destinato solo a operazioni collettive come l'esportazione o la scansione dell'intero database.
Puoi eseguire qualsiasi operazione di lettura dell'API in parallelo utilizzando le librerie client Spanner. Tuttavia, puoi partizionare le query SQL solo quando le query sono partizionabili come root. Affinché una query sia partizionabile alla radice, il piano di query deve soddisfare una delle seguenti condizioni:
Il primo operatore nel piano di esecuzione delle query è un'unione distribuita e il piano di esecuzione delle query contiene solo un'unione distribuita (esclusi i gruppi di distribuzione locali). Il piano di query non può contenere altri operatori distribuiti, ad esempio applicazione incrociata distribuita.
Non sono presenti operatori distribuiti nel piano di query.
L'API PartitionQuery
esegue le query in modalità batch. Spanner può scegliere un piano di esecuzione delle query che rende le query partizionabili come root 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 ottenere il piano di esecuzione della query utilizzato dall'API PartitionQuery
su Spanner Studio.
Per le query partizionate come questa, puoi scegliere di abilitare Spanner Data Boost. Data Boost consente di eseguire query di analisi di grandi dimensioni con un impatto prossimo allo zero sui carichi di lavoro esistenti sull'istanza di Spanner di cui è stato eseguito il provisioning. Gli esempi di codice C++, Go, Java, Node.js e Python in questa pagina mostrano come abilitare Data Boost.
Per ulteriori informazioni su Data Boost, consulta la 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 seguendo questi passaggi:
- Creazione di una transazione batch Spanner in corso.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di una transazione batch Spanner in corso.
- Generazione di partizioni per la query, in modo che possano essere distribuite a più worker.
- Recupero dei risultati della query per ogni partizione.
Go
Questo esempio recupera le partizioni di una query SQL della tabella Singers
ed esegue la query su ogni partizione seguendo questi passaggi:
- Creazione di un client Spanner e di una transazione.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client batch Spanner e di una transazione.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client Spanner e di un batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client Spanner e di un batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client Spanner e di una transazione batch.
- Generazione di partizioni per la query, in modo che possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client batch Spanner.
- Creazione di partizioni per la query, in modo che possano essere distribuite a più worker.
- Recupero dei risultati della query per ogni partizione.