Esta página descreve como realizar leituras no Spanner fora do contexto de transações somente leitura e de leitura e gravação. Se uma das seguintes condições for verdadeira, leia a página Transações:
Se você precisa gravar, dependendo do valor de uma ou mais leituras, precisa executar a leitura como parte de uma transação de leitura e gravação. Para mais informações, consulte Transações de leitura e gravação.
Se você estiver fazendo várias chamadas de leitura que exigem uma visão consistente dos dados, precisará executar as leituras como parte de uma transação somente leitura. Para mais informações, consulte Transações somente leitura.
Tipos de leitura
O Spanner permite determinar o nível de atualização dos dados quando lidos por meio dos dois tipos de leitura oferecidos:
- Uma leitura forte é uma leitura em um carimbo de data/hora atual. Esse tipo de leitura garante que todos os dados que foram confirmados até o início dela serão vistos. O padrão do Spanner é usar leituras fortes para atender a solicitações de leitura.
- Uma leitura desatualizada é uma leitura em um carimbo de data/hora no passado. Se o aplicativo for sensível à latência, mas tolerante a dados desatualizados, as leituras desatualizadas representarão benefícios no desempenho.
Para escolher o tipo de leitura que você quer, defina um limite de carimbo de data/hora na solicitação de leitura. Use as seguintes práticas recomendadas ao escolher um limite de carimbo de data/hora:
Escolha leituras fortes sempre que possível. Esse é o carimbo de data/hora padrão para leituras do Spanner, incluindo transações somente leitura. As leituras fortes têm garantia de visualização dos efeitos de todas as transações que tenham sido confirmadas antes do início da operação, independentemente de qual réplica receba a leitura. Por causa disso, as leituras fortes tornam os aplicativos mais confiáveis e simplificam o código deles. Saiba mais sobre as propriedades de consistência do Spanner em TrueTime e consistência externa.
Se a latência tornar as leituras fortes inviáveis em algumas situações, use leituras desatualizadas (inatividade limitada ou exata) para melhorar o desempenho em locais em que não é necessário que as leituras sejam as mais recentes possíveis. Como descrito na página Replicação, 15 segundos é um valor de inatividade razoável para ter um bom desempenho.
Ler dados com uma função de banco de dados
Se você for um usuário de controle de acesso minucioso, selecione uma função de banco de dados para executar instruções e consultas SQL e realizar operações de linha em um banco de dados. A seleção de função persiste durante toda a sessão até que você mude a função.
Para instruções sobre como realizar uma leitura com uma função do banco de dados, consulte Acessar um banco de dados com controle de acesso detalhado.
Métodos de leitura única
O Spanner oferece suporte a métodos de leitura única (ou seja, uma leitura fora do contexto de uma transação) em um banco de dados para:
- Executar a leitura como uma instrução de consulta SQL ou usar a API de leitura do Spanner.
- realizar uma leitura forte de uma única linha ou de várias linhas em uma tabela;
- realizar uma leitura desatualizada de uma única linha ou várias linhas em uma tabela;
- ler uma única linha ou várias linhas em um índice secundário.
Se você quiser encaminhar leituras únicas para uma réplica ou região específica em uma configuração de instância multirregional ou uma configuração regional personalizada com regiões somente leitura opcionais, consulte Leituras direcionadas.
As seções a seguir descrevem como usar métodos de leitura com bibliotecas de cliente do Spanner.
Executar uma consulta
Veja a seguir como executar uma instrução de consulta SQL em um banco de dados.
GoogleSQL
C++
Use ExecuteQuery()
para executar uma instrução de consulta SQL em um banco de dados.
C#
Use ExecuteReaderAsync()
para consultar o banco de dados.
Go
Use Client.Single().Query
para consultar o banco de dados.
Java
Use ReadContext.executeQuery
para consultar o banco de dados.
Node.js
Use Database.run
para consultar o banco de dados.
PHP
Use Database::execute
para consultar o banco de dados.
Python
Use Database.execute_sql
para consultar o banco de dados.
Ruby
Use Client#execute
para consultar o banco de dados.
No SQL, consulte as referências Sintaxe de consulta e Funções e operadores ao criar uma instrução SQL.
Executar uma leitura forte
O exemplo a seguir mostra como executar uma leitura forte de zero ou mais linhas de um banco de dados.
GoogleSQL
C++
O código para ler dados é o mesmo do exemplo anterior para consultar o Spanner por meio da execução de uma consulta SQL.
C#
O código para ler dados é o mesmo do exemplo anterior para consultar o Spanner por meio da execução de uma consulta SQL.
Go
Use Client.Single().Read
para ler as linhas do banco de dados.
O exemplo usa AllKeys
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Java
Use ReadContext.read
para ler as linhas do banco de dados.
O exemplo usa KeySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Node.js
Use Table.read
para ler as linhas do banco de dados.
O exemplo usa keySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
PHP
Use Database::read
para ler as linhas do banco de dados.
O exemplo usa keySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Python
Use Database.read
para ler as linhas do banco de dados.
O exemplo usa KeySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Ruby
Use Client#read
para ler as linhas do banco de dados.
Executar uma leitura desatualizada
No código de amostra a seguir, explicamos como executar uma leitura desatualizada de zero ou mais linhas de um banco de dados usando um limite de carimbo de data/hora inatividade exata. Para receber instruções de como executar uma leitura desatualizada usando um limite de carimbo de data/hora de inatividade limitada, veja a observação após o código de amostra. Consulte Limites de carimbo de data/hora para mais informações sobre os diferentes tipos de limites de carimbos de data/hora disponíveis.
GoogleSQL
C++
Use ExecuteQuery()
com MakeReadOnlyTransaction()
e Transaction::ReadOnlyOptions()
para executar uma leitura desatualizada.
C#
Use o método BeginReadOnlyTransactionAsync
em um connection
com um valor TimestampBound.OfExactStaleness()
especificado para consultar o banco de dados.
Go
Use Client.ReadOnlyTransaction().WithTimestampBound()
e especifique um valor ExactStaleness
para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data e hora de exatidão.
O exemplo usa AllKeys
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Java
Use o método read
de um ReadContext
que tenha um TimestampBound.ofExactStaleness()
especificado para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data e hora com inatividade exata.
O exemplo usa KeySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Node.js
Use Table.read
com a opção exactStaleness
para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data e hora de inatividade exata.
O exemplo usa keySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
PHP
Use Database::read
com um valor exactStaleness
especificado para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data e hora de inatividade exata.
O exemplo usa keySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Python
Use o método read
de um Database
snapshot
que tenha um exact_staleness
especificado para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data e hora com inatividade exata.
O exemplo usa KeySet
para definir um conjunto de chaves ou intervalos de chaves a serem lidos.
Ruby
Use o método read
de um de snapshot Client
que tenha um valor de staleness
especificado (em segundos) para executar uma leitura de linhas do banco de dados usando um limite de carimbo de data/hora de inatividade exata.
Executar uma leitura usando um índice
Confira a seguir como ler zero ou mais linhas de um banco de dados usando um índice:
GoogleSQL
C++
Use a função Read()
para realizar uma leitura usando um índice.
C#
Execute uma consulta que especifica explicitamente um índice a ser usado para fazer leituras de dados:
Go
Use Client.Single().ReadUsingIndex
para ler linhas do banco de dados usando um índice.
Java
Use ReadContext.readUsingIndex
para ler linhas do banco de dados usando um índice.
Node.js
Use Table.read
e especifique o índice na consulta para ler linhas do banco de dados usando um índice.
PHP
Use Database::read
e especifique o índice para ler linhas do banco de dados usando um índice.
Python
Use Database.read
e especifique o índice para ler linhas do banco de dados usando um índice.
Ruby
Use Client#read
e especifique o índice para ler linhas do banco de dados usando um índice.
Ler dados em paralelo
Ao executar operações de leitura ou consulta em massa que envolvem grandes quantidades de dados do Spanner, use a API PartitionQuery
para resultados mais rápidos. A API divide a consulta em lotes ou
partições usando várias máquinas para buscar as partições em paralelo. O uso da API PartitionQuery
causa uma latência maior porque ela é destinada apenas a operações em massa, como exportar ou verificar todo o banco de dados.
Realize qualquer operação da API de leitura em paralelo usando as bibliotecas de cliente do Spanner. No entanto, só é possível particionar consultas SQL quando elas são particionáveis pela raiz. Para que uma consulta possa ser particionada pela raiz, o plano de consulta precisa atender a uma das seguintes condições:
O primeiro operador no plano de execução da consulta é uma union distribuída, e o plano de execução da consulta contém apenas uma union distribuída (exceto union de distribuição local). O plano de consulta não pode conter outros operadores distribuídos, como a aplicação cruzada distribuída.
Não há operadores distribuídos no plano de consulta.
A API PartitionQuery
executa as consultas no modo em lote. O Spanner
pode escolher um plano de execução de consulta que torna as consultas particionáveis pela raiz
quando executadas no modo em lote. Como resultado, a API PartitionQuery
e
o Spanner Studio podem usar planos de execução de consulta diferentes
para a mesma consulta. Talvez não seja possível acessar o plano de execução de consulta
usado pela API PartitionQuery
no Spanner Studio.
Para consultas particionadas como essa, você pode ativar o Data Boost do Spanner. O Data Boost permite executar consultas analíticas grandes com impacto quase zero nas cargas de trabalho atuais na instância provisionada do Spanner. Os exemplos de código C++, Go, Java, Node.js e Python desta página mostram como ativar o Data Boost.
Para mais informações sobre o Data Boost, consulte Visão geral do Data Boost.
GoogleSQL
C++
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar uma transação em lote do Spanner.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
C#
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar uma transação em lote do Spanner.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
Go
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente do Spanner e uma transação.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
Java
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente de lote do Spanner e uma transação.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
Node.js
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente do Spanner e um lote.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
PHP
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente do Spanner e um lote.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
Python
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente do Spanner e uma transação em lote.
- Gerar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.
Ruby
Este exemplo busca partições de uma consulta SQL da tabela Singers
e
executa a consulta sobre cada partição por meio das seguintes etapas:
- Criar um cliente de lote do Spanner.
- Criar partições da consulta. Dessa maneira, as partições podem ser distribuídas para vários trabalhadores.
- Recuperar os resultados da consulta para cada partição.