En esta página, se describe cómo realizar lecturas en Spanner fuera del contexto de las transacciones de solo lectura y de lectura y escritura. Si se aplica alguna de las siguientes situaciones, deberías leer la página sobre transacciones en su lugar:
Si necesitas escribir, en función del valor de una o más lecturas, debes ejecutar la lectura como parte de una transacción de lectura y escritura. Para obtener más información, consulta la sección sobre transacciones de lectura y escritura.
Si realizas varias llamadas de lectura que requieren una vista coherente de tus datos, debes ejecutar las lecturas como parte de una transacción de solo lectura. Para obtener más información, consulta transacciones de solo lectura.
Tipos de lecturas
Spanner te permite determinar qué tan actuales deben ser los datos para leerlos. Para esto, ofrece dos tipos de lecturas:
- Una lectura sólida es una lectura en una marca de tiempo actual y se garantiza que se ven todos los datos que se hayan confirmado hasta el inicio de esta lectura. Spanner usa lecturas sólidas de forma predeterminada para entregar solicitudes de lectura.
- Una lectura inactiva se lee en una marca de tiempo anterior. Si tu aplicación es sensible a la latencia, pero tolera los datos obsoletos, las lecturas inactivas pueden proporcionar beneficios de rendimiento.
Para elegir qué tipo de lectura quieres, configura un límite de marca de tiempo en la solicitud de lectura. Usa las siguientes prácticas recomendadas cuando elijas un límite de marca de tiempo:
Elige lecturas sólidas siempre que sea posible. Son el límite predeterminado de marca de tiempo de las lecturas de Spanner, incluidas las transacciones de solo lectura. Se garantiza que las lecturas sólidas observan los efectos de todas las transacciones que se confirmaron antes del inicio de la operación, sin importar de qué réplica reciba la lectura. Debido a esto, las lecturas sólidas hacen que el código de la aplicación sea más simple y que las aplicaciones sean más confiables. Obtén más información sobre las propiedades de coherencia de Spanner en TrueTime y la coherencia externa.
Si la latencia vuelve inviables las lecturas sólidas en algunas situaciones, usa lecturas inactivas (de inactividad limitada o exacta) para mejorar el rendimiento en lugares donde no necesitas que las lecturas sean lo más recientes posible. Como se describe en la página Replicación, 15 segundos es un valor de inactividad razonable para obtener un buen rendimiento.
Cómo leer datos con un rol de base de datos
Si eres un usuario del control de acceso detallado, debes seleccionar un rol de base de datos para ejecutar instrucciones y consultas de SQL, y para realizar operaciones de fila en una base de datos. La selección de roles persiste durante toda la sesión hasta que cambias el rol.
Si deseas obtener instrucciones para realizar una operación de lectura con un rol de base de datos, consulta Cómo acceder a una base de datos con control de acceso detallado.
Métodos de lectura única
Spanner admite métodos de operación de lectura única (es decir, una operación de lectura fuera del contexto de una transacción) en una base de datos para realizar las siguientes acciones:
- Ejecutar la lectura como una instrucción de consulta de SQL o usar la API de lectura de Spanner
- Realizar una lectura sólida desde una o varias filas de una tabla
- Realizar una lectura inactiva desde una o varias filas en una tabla
- Leer desde una o varias filas en un índice secundario
Si deseas enrutar operaciones de lectura únicas a una réplica o región específicas dentro de una configuración de instancias multirregionales o una configuración regional personalizada con regiones de solo lectura opcionales, consulta Operaciones de lectura dirigidas.
En las siguientes secciones, se describe cómo usar los métodos de lectura con las bibliotecas cliente de Spanner.
Ejecuta una consulta
A continuación, se muestra cómo ejecutar una instrucción de consulta de SQL en una base de datos.
GoogleSQL
C++
Usa ExecuteQuery()
para ejecutar una instrucción de consulta de SQL en una base de datos.
C#
Usa ExecuteReaderAsync()
para consultar la base de datos.
Go
Usa Client.Single().Query
para consultar la base de datos.
Java
Usa ReadContext.executeQuery
para consultar la base de datos.
Node.js
Usa Database.run
para consultar la base de datos.
PHP
Usa Database::execute
para consultar la base de datos.
Python
Usa Database.execute_sql
para consultar la base de datos.
Ruby
Usa Client#execute
para consultar la base de datos.
Consulta Expresiones, funciones y operadores y la página sobre la sintaxis de consulta de SQL cuando crees una instrucción de SQL.
Realizar una lectura sólida
A continuación, se muestra cómo realizar una lectura sólida de cero o más filas en una base de datos.
GoogleSQL
C++
El código de lectura de datos es el mismo que el ejemplo anterior para consultar Spanner mediante la ejecución de una consulta de SQL.
C#
El código de lectura de datos es el mismo que el ejemplo anterior para consultar Spanner mediante la ejecución de una consulta de SQL.
Go
Usa Client.Single().Read
para leer filas de la base de datos.
En el ejemplo, se usa AllKeys
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Java
Usa ReadContext.read
para leer filas de la base de datos.
En el ejemplo, se usa KeySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Node.js
Usa Table.read
para leer filas de la base de datos.
En el ejemplo, se usa keySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
PHP
Usa Database::read
para leer filas de la base de datos.
En el ejemplo, se usa keySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Python
Usa Database.read
para leer filas de la base de datos.
En el ejemplo, se usa KeySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Ruby
Usa Client#read
para leer filas de la base de datos.
Realizar una lectura inactiva
En el siguiente ejemplo de código, se muestra cómo realizar una lectura inactiva de cero o más filas de una base de datos mediante un límite de marca de tiempo de inactividad exacta. Si quieres obtener instrucciones para realizar una lectura inactiva mediante un límite de marca de tiempo de inactividad limitada, consulta la nota que se encuentra después del código de muestra. Consulta la página sobre límites de marca de tiempo para obtener más información sobre los distintos tipos de límites de marca de tiempo disponibles.
GoogleSQL
C++
Usa ExecuteQuery()
con MakeReadOnlyTransaction()
y Transaction::ReadOnlyOptions()
para realizar una lectura inactiva.
C#
Usa el método BeginReadOnlyTransactionAsync
en una connection
con un valor especificado TimestampBound.OfExactStaleness()
para consultar la base de datos.
Go
Usa Client.ReadOnlyTransaction().WithTimestampBound()
y especifica un valor ExactStaleness
para realizar una lectura de las filas de la base de datos mediante un límite de marca de tiempo de inactividad exacta.
En el ejemplo, se usa AllKeys
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Java
Usa el método read
de un ReadContext
que tenga un TimestampBound.ofExactStaleness()
especificado para realizar una lectura de las filas de la base de datos mediante un límite de marca de tiempo de inactividad exacta.
En el ejemplo, se usa KeySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Node.js
Usa Table.read
con la opción exactStaleness
para realizar una lectura de las filas de la base de datos con un límite de marca de tiempo de inactividad exacta.
En el ejemplo, se usa keySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
PHP
Usa Database::read
con un valor exactStaleness
especificado para realizar una lectura de las filas de la base de datos mediante un límite de marca de tiempo de inactividad exacta.
En el ejemplo, se usa keySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Python
Usa el método read
de la snapshot
de una Database
que tenga un valor exact_staleness
especificado para realizar una lectura de las filas de la base de datos mediante un límite de marca de tiempo de inactividad exacta.
En el ejemplo, se usa KeySet
para definir una colección de claves o rangos de claves a fin de realizar lecturas.
Ruby
Usa el método read
del Client
de una instantánea que tenga un valor staleness
especificado (en segundos) para leer filas de la base de datos mediante un límite de marca de tiempo de inactividad exacta.
Realizar una lectura mediante un índice
A continuación, se muestra cómo leer cero o más filas de una base de datos mediante un índice:
GoogleSQL
C++
Usa la función Read()
para realizar una lectura mediante un índice.
C#
Para leer los datos mediante el índice, ejecuta una consulta que especifique el índice de forma explícita:
Go
Usa Client.Single().ReadUsingIndex
para leer filas de la base de datos mediante un índice.
Java
Usa ReadContext.readUsingIndex
para leer filas de la base de datos mediante un índice.
Node.js
Usa Table.read
y especifica el índice en la consulta para leer filas de la base de datos mediante un índice.
PHP
Usa Database::read
y especifica el índice para leer filas de la base de datos mediante un índice.
Python
Usa Database.read
y especifica el índice para leer filas de la base de datos mediante un índice.
Ruby
Usa Client#read
y especifica el índice para leer filas de la base de datos mediante un índice.
Leer datos en paralelo
Cuando realices operaciones de lectura o consulta masivas que involucren grandes cantidades de datos de Spanner, puedes usar la API de PartitionQuery
para obtener resultados más rápidos. La API divide la consulta en lotes, o particiones, con varias máquinas para recuperar las particiones en paralelo. Ten en cuenta que el uso de la API de PartitionQuery
genera una latencia más alta, ya que solo está diseñado para operaciones masivas, como exportar o analizar toda la base de datos.
Puedes realizar cualquier operación de la API de lectura en paralelo mediante las bibliotecas cliente de Spanner. Sin embargo, solo puedes particionar las consultas de SQL cuando estas se pueden particionar en la raíz. Para que una consulta se pueda particionar en raíz, el plan de consulta debe satisfacer una de las siguientes condiciones:
El primer operador del plan de ejecución de consultas es una unión distribuida y el plan de ejecución de consultas solo contiene una unión distribuida (sin contar las uniones de distribución locales). Tu plan de consultas no puede contener ningún otro operador distribuido, como aplicación cruzada distribuida.
No hay operadores distribuidos en el plan de consultas.
La API de PartitionQuery
ejecuta las consultas en modo por lotes. Spanner podría elegir un plan de ejecución de consultas que haga que las consultas se puedan particionar en raíz cuando se ejecuten en modo por lotes. Como resultado, es posible que la API de PartitionQuery
y Spanner Studio usen diferentes planes de ejecución de consultas para la misma consulta. Es posible que no puedas obtener el plan de ejecución de consultas que usa la API de PartitionQuery
en Spanner Studio.
Para consultas particionadas como esta, puedes habilitar Data Boost de Spanner. Data Boost te permite ejecutar consultas de análisis grandes con un impacto casi nulo en las cargas de trabajo existentes de la instancia de Spanner aprovisionada. En los ejemplos de código de C++, Go, Java, Node.js y Python que se muestran en esta página, se explica cómo habilitar el aumento de datos.
Para obtener más información sobre Data Boost, consulta Descripción general de Data Boost.
GoogleSQL
C++
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea una transacción por lotes de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
C#
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea una transacción por lotes de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
Go
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente y una transacción de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
Java
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente por lotes y una transacción de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
Node.js
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente y un lote de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
PHP
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente y un lote de Spanner.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
Python
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente de Spanner y una transacción por lotes.
- Genera particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recupera los resultados de la consulta en cada partición.
Ruby
En este ejemplo, se recuperan las particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición mediante los siguientes pasos:
- Crea un cliente por lotes de Spanner.
- Crea particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores
- Recupera los resultados de la consulta en cada partición.