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 da alguna de las siguientes situaciones, consulta la página Transacciones:
Si necesitas escribir en función del valor de una o varias lecturas, debes ejecutar la lectura como parte de una transacción de lectura y escritura. Para obtener más información, consulta Transacciones de lectura y escritura.
Si vas a hacer varias llamadas de lectura que requieran 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 el artículo sobre las transacciones de solo lectura.
Leer tipos
Spanner te permite determinar la actualidad de los datos cuando los lees. Para ello, ofrece dos tipos de lecturas:
- Una lectura sólida es una lectura en una marca de tiempo actual y tiene la garantía de ver todos los datos que se han confirmado hasta el inicio de esta lectura. Spanner usa de forma predeterminada lecturas sólidas para atender las solicitudes de lectura.
- Una lectura inactiva se lee en una marca de tiempo en el pasado. Si tu aplicación es sensible a la latencia, pero tolera los datos obsoletos, las lecturas obsoletas pueden ofrecer ventajas de rendimiento.
Para elegir el tipo de lectura que quieras, define un límite de marca de tiempo en la solicitud de lectura. Sigue estas prácticas recomendadas al elegir un límite de marca de tiempo:
Elige lecturas fuertes siempre que sea posible. Esta es la marca de tiempo predeterminada 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 completaron antes del inicio de la operación, independientemente de la réplica que reciba la lectura. Por este motivo, las lecturas sólidas simplifican el código de las aplicaciones y hacen que estas sean más fiables. Consulta más información sobre las propiedades de coherencia de Spanner en TrueTime y coherencia externa.
Si la latencia hace que las lecturas sólidas no sean viables en algunas situaciones, utiliza lecturas obsoletas (obsolescencia limitada u obsolescencia exacta) para mejorar el rendimiento en los casos en los que no necesites que las lecturas sean lo más recientes posible. Como se describe en la página Replicación, 15 segundos es un valor de obsolescencia razonable para obtener un buen rendimiento.
Leer datos con un rol de base de datos
Si eres usuario del control de acceso pormenorizado, debes seleccionar un rol de base de datos para ejecutar instrucciones y consultas SQL, así como para realizar operaciones de fila en una base de datos. La función que elijas se mantendrá durante toda la sesión hasta que la cambies.
Para obtener instrucciones sobre cómo realizar una lectura con un rol de base de datos, consulta Acceder a una base de datos con un control de acceso pormenorizado.
Métodos de lectura única
Spanner admite métodos de lectura única (es decir, una lectura fuera del contexto de una transacción) en una base de datos para lo siguiente:
- Ejecutar la lectura como una instrucción de consulta de SQL o mediante la API de lectura de Spanner.
- Realizar una lectura fuerte desde una sola fila o varias filas en una tabla.
- Realizar una lectura inactiva de una sola fila o varias filas en una tabla.
- Leer desde una sola fila o varias filas en un índice secundario.
Si quieres dirigir lecturas únicas a una réplica o región específicas en una configuración de instancia multirregional o en una configuración regional personalizada con una o varias regiones de solo lectura opcionales, consulta Lecturas dirigidas.
En las siguientes secciones se describe cómo usar los métodos de lectura con las bibliotecas de cliente de Spanner.
Ejecutar una consulta
A continuación, se muestra cómo ejecutar una instrucción de consulta SQL en una base de datos.
GoogleSQL
C++
Usa ExecuteQuery()
para ejecutar una instrucción de consulta 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 las referencias de sintaxis de consultas y funciones y operadores de SQL al crear una instrucción SQL.
Realizar una lectura fuerte
A continuación, se muestra cómo realizar una lectura fuerte de cero o más filas desde una base de datos.
GoogleSQL
C++
El código para leer datos es el mismo que en el ejemplo anterior para consultar Spanner ejecutando una consulta SQL.
C#
El código para leer datos es el mismo que en el ejemplo anterior para consultar Spanner ejecutando una consulta 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 intervalos de claves que se van a leer.
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 intervalos de claves que se van a leer.
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 intervalos de claves que se van a leer.
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 intervalos de claves que se van a leer.
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 intervalos de claves que se van a leer.
Ruby
Usa Client#read
para leer filas de la base de datos.
Realizar una lectura inactiva
El siguiente código de ejemplo muestra cómo realizar una lectura inactiva de cero o más filas de una base de datos mediante el uso de un límite de una marca de tiempo inactivo exacta. Para obtener instrucciones sobre cómo realizar una lectura obsoleta con un límite de tiempo bounded-staleness, consulta la nota que aparece después del código de ejemplo. Consulta Límites de marcas de tiempo para obtener más información sobre los distintos tipos de límites de marcas de tiempo disponibles.
GoogleSQL
C++
Usa ExecuteQuery()
con MakeReadOnlyTransaction()
y Transaction::ReadOnlyOptions()
para realizar una lectura obsoleta.
C#
Usa el método BeginReadOnlyTransactionAsync
en un connection
con un valor TimestampBound.OfExactStaleness()
especificado para consultar la base de datos.
Go
Usa Client.ReadOnlyTransaction().WithTimestampBound()
y especifica un valor de ExactStaleness
para leer filas de la base de datos usando un límite de marca de tiempo de obsolescencia exacto.
En el ejemplo se usa AllKeys
para definir una colección de claves o intervalos de claves que se van a leer.
Java
Usa el método read
de un ReadContext
que tenga un TimestampBound.ofExactStaleness()
especificado para leer filas de la base de datos con un límite de marca de tiempo de obsolescencia exacto.
En el ejemplo se usa KeySet
para definir una colección de claves o intervalos de claves que se van a leer.
Node.js
Usa Table.read
con la opción exactStaleness
para leer filas de la base de datos con un límite de marca de tiempo de obsolescencia exacto.
En el ejemplo se usa keySet
para definir una colección de claves o intervalos de claves que se van a leer.
PHP
Usa Database::read
con un valor de exactStaleness
especificado para leer filas de la base de datos con un límite de marca de tiempo de obsolescencia exacto.
En el ejemplo se usa keySet
para definir una colección de claves o intervalos de claves que se van a leer.
Python
Usa el método read
de un Database
snapshot
que tenga un valor de exact_staleness
especificado para leer filas de la base de datos mediante un límite de marca de tiempo de obsolescencia exacto.
En el ejemplo se usa KeySet
para definir una colección de claves o intervalos de claves que se van a leer.
Ruby
Usa el método read
de una instantánea Client
que tenga un valor staleness
especificado (en segundos) para leer filas de la base de datos usando un límite de marca de tiempo de obsolescencia exacto.
Realizar una lectura mediante el uso de 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 con un índice.
C#
Lee datos mediante el índice ejecutando una consulta que especifique explícitamente el índice:
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 realice operaciones de lectura o consulta masivas que impliquen grandes cantidades de datos de Spanner, puede usar la API PartitionQuery
para obtener resultados más rápido. La API divide la consulta en lotes o particiones mediante varias máquinas para obtener las particiones en paralelo. Ten en cuenta que el uso de la API PartitionQuery
provoca una latencia mayor, ya que solo está pensada para operaciones masivas, como exportar o analizar toda la base de datos.
Puedes realizar cualquier operación de API de lectura en paralelo mediante las bibliotecas de cliente de Spanner. Sin embargo, solo puedes particionar consultas SQL cuando las consultas se pueden particionar por la raíz. Para que una consulta se pueda particionar por raíz, el plan de consulta debe cumplir una de las siguientes condiciones:
El primer operador del plan de ejecución de la consulta es una unión distribuida y el plan de ejecución de la consulta solo contiene una unión distribuida (sin incluir las uniones de distribución local). Tu plan de consulta no puede contener ningún otro operador distribuido, como aplicación cruzada distribuida.
No hay operadores distribuidos en el plan de consulta.
La API PartitionQuery
ejecuta las consultas en modo por lotes. Spanner puede elegir un plan de ejecución de consultas que haga que las consultas se puedan particionar por raíz
cuando se ejecuten en modo por lotes. Por lo tanto, es posible que la API PartitionQuery
y Spanner Studio usen planes de ejecución de consultas diferentes para la misma consulta. Es posible que no puedas obtener el plan de ejecución de consultas que usa la API PartitionQuery
en Spanner Studio.
En el caso de las consultas particionadas como esta, puede habilitar Spanner Data Boost. Data Boost te permite ejecutar consultas analíticas de gran tamaño con un impacto casi nulo en las cargas de trabajo de la instancia de Spanner aprovisionada. Los ejemplos de código de C++, Go, Java, Node.js y Python de esta página muestran cómo habilitar Data Boost.
Para obtener más información sobre Data Boost, consulta el artículo de introducción a Data Boost.
GoogleSQL
C++
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear una transacción por lotes de Spanner.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
C#
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear una transacción por lotes de Spanner.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
Go
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de Spanner y una transacción.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
Java
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de Spanner por lotes y una transacción.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
Node.js
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de Spanner y un lote.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
PHP
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de Spanner y un lote.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
Python
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de Spanner y una transacción por lotes.
- Generar particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.
Ruby
En este ejemplo se obtienen particiones de una consulta de SQL de la tabla Singers
y se ejecuta la consulta en cada partición siguiendo estos pasos:
- Crear un cliente de lote de Spanner.
- Crear particiones para la consulta, de modo que las particiones se puedan distribuir a varios trabajadores.
- Recuperar los resultados de la consulta para cada partición.