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 in base al valore di una o più letture, devi eseguire la lettura nell'ambito di una transazione di lettura/scrittura. Per ulteriori informazioni, consulta la sezione Transazioni di lettura/scrittura.
Se esegui più chiamate di lettura che richiedono una visualizzazione coerente dei dati, devi eseguire le letture nell'ambito di una transazione di sola lettura. Per maggiori informazioni, consulta la sezione Transazioni di sola lettura.
Tipi di lettura
Spanner ti consente di determinare l'attualità dei dati quando li leggi offrendo due tipi di lettura:
- Una lettura coerente è una lettura a un timestamp corrente e garantisce di visualizzare tutti i dati di cui è stato eseguito il commit fino all'inizio della lettura. Per impostazione predefinita, Spanner utilizza letture coerenti per gestire le richieste di lettura.
- Una lettura obsoleta viene eseguita a un timestamp nel passato. Se la tua applicazione è sensibile alla latenza, ma tollera i dati obsoleti, le letture obsolete possono fornire vantaggi in termini di prestazioni.
Per scegliere il tipo di lettura che preferisci, imposta un limite temporale nella richiesta di lettura. Segui queste best practice quando scegli un limite di timestamp:
Scegli letture forti ogni volta che è possibile. Questi sono i limiti temporali predefiniti per le letture di Spanner, incluse le transazioni di sola lettura. Le letture coerenti garantiscono l'osservanza degli effetti di tutte le transazioni di cui è stato eseguito il commit prima dell'inizio dell'operazione, indipendentemente dalla replica che riceve la lettura. Per questo motivo, le letture coerenti 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 coerenti in alcune situazioni, utilizza le letture obsolete (obsolescenza 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 Replicazione, 15 secondi è un valore di obsolescenza ragionevole da utilizzare per ottenere buone prestazioni.
Lettura di dati con un ruolo database
Se utilizzi il 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 rimane valida per tutta la sessione finché non lo modifichi.
Per istruzioni su come eseguire una lettura con un ruolo del database, vedi Accedere a un database con il controllo dell'accesso granulare.
Metodi di lettura singoli
Spanner supporta i metodi di lettura singoli (ovvero una lettura al di fuori del contesto di una transazione) su un database per:
- Eseguendo la lettura come istruzione di query SQL o utilizzando l'API di lettura di Spanner.
- Esecuzione di una lettura coerente da una o più righe di una tabella.
- Esecuzione di una lettura obsoleta da una o più righe di una tabella.
- Lettura da una singola riga o da più righe in un indice secondario.
Se vuoi indirizzare le singole letture a una replica o una regione specifica all'interno di una configurazione di istanza multiregionale o di una configurazione regionale personalizzata con una o più regioni di sola lettura facoltative, consulta Letture dirette.
Le sezioni seguenti descrivono come utilizzare i metodi di lettura utilizzando le librerie client Spanner.
Eseguire 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 crei un'istruzione SQL.
Eseguire una lettura efficace
Di seguito viene mostrato come eseguire una lettura coerente di zero o più righe da un database.
GoogleSQL
C++
Il codice per leggere i dati è lo stesso dell'esempio precedente per l'interrogazione di Spanner mediante l'esecuzione di una query SQL.
C#
Il codice per leggere i dati è lo stesso dell'esempio precedente per l'interrogazione di Spanner mediante l'esecuzione di 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 campione mostra come eseguire una lettura obsoleta di zero o più righe da un database utilizzando un limite temporale exact-staleness. Per istruzioni su come eseguire una lettura obsoleta utilizzando un limite temporale di obsolescenza controllata, consulta la nota dopo il codice campione. 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 obsoleta.
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 obsolescenza 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 TimestampBound.ofExactStaleness()
specificato per eseguire una lettura delle righe dal database utilizzando un limite di timestamp di obsolescenza esatto.
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 obsolescenza esatta.
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 obsolescenza 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 obsolescenza esatta.
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 delle righe dal database utilizzando un limite di timestamp di obsolescenza esatto.
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 o query collettive che coinvolgono grandi quantità di
dati da Spanner, puoi utilizzare l'API PartitionQuery
per 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 perché
è destinata solo a operazioni collettive come l'esportazione o la scansione dell'intero
database.
Puoi eseguire qualsiasi operazione API di lettura in parallelo utilizzando le librerie client Spanner. Tuttavia, puoi partizionare le query SQL solo quando sono partizionabili a livello di radice. Affinché una query possa essere partizionata a livello di 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 (escluse le unioni di distribuzione locale). Il piano di query non può contenere altri operatori distribuiti, ad esempio cross-apply distribuito.
Non sono presenti operatori distribuiti nel piano di query.
L'API PartitionQuery
esegue le query in modalità batch. Spanner
potrebbe scegliere un piano di esecuzione delle query che le rende partizionabili a livello di 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 essere in grado di ottenere il piano di esecuzione query
utilizzato dall'API PartitionQuery
in 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 Data Boost.
Per saperne di più 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.
- Generazione di partizioni per la query, in modo che le partizioni 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.
- Generazione di partizioni per la query, in modo che le partizioni possano essere distribuite a 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 seguendo questi passaggi:
- Creazione di un client Spanner e di una transazione.
- Generazione di partizioni per la query, in modo che le partizioni 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 le partizioni 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 le partizioni 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 le partizioni 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 le partizioni 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 le partizioni possano essere distribuite a più worker.
- Recupero dei risultati della query per ogni partizione.