En esta página, se describen las prácticas recomendadas para usar el lenguaje de manipulación de datos (DML) y el DML particionado.
Usa una cláusula WHERE para reducir el alcance de los bloqueos
Las declaraciones DML se pueden ejecutar dentro de transacciones de lectura y escritura. Cuando Spanner lee datos,
adquiere bloqueos de lectura compartidos en porciones limitadas de los rangos de filas que lees. En particular, adquiere estos bloqueos solo en las columnas a las que accedes. Las cerraduras pueden incluir datos que no
satisface la condición de filtro de la cláusula WHERE
.
Cuando Spanner modifica los datos mediante declaraciones DML, adquiere bloqueos exclusivos en la los datos específicos que estás modificando. Además, adquiere bloqueos compartidos de la misma manera que cuando lees datos. Si tu solicitud incluye grandes rangos de filas o una tabla completa, es posible que los bloqueos compartidos impidan que otras transacciones progresen en paralelo.
Para modificar los datos de la manera más eficiente posible, usa una cláusula WHERE
que permita a Spanner leer solo las filas necesarias. Puedes lograr este objetivo con un filtro en la clave primaria o en la clave de un índice secundario. La cláusula WHERE
limita el alcance de los bloqueos compartidos y permite que Spanner procese la actualización de manera más eficiente.
Por ejemplo, supongamos que uno de los músicos de la tabla Singers
cambia su nombre y tienes que actualizarlo en tu base de datos. Puedes ejecutar el siguiente archivo DML
pero obliga a Spanner a analizar toda la tabla y adquirir bloqueos compartidos que
cubrir toda la tabla. Como resultado, Spanner debe leer más datos de los necesarios.
Las transacciones simultáneas no pueden modificar los datos en paralelo:
-- ANTI-PATTERN: SENDING AN UPDATE WITHOUT THE PRIMARY KEY COLUMN
-- IN THE WHERE CLAUSE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards";
Para que la actualización sea más eficiente, incluye la columna SingerId
en la cláusula WHERE
. La columna SingerId
es la única columna de clave primaria de la tabla Singers
:
-- ANTI-PATTERN: SENDING AN UPDATE THAT MUST SCAN THE ENTIRE TABLE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards"
Si no hay un índice en FirstName
o LastName
, debes hacer lo siguiente:
analizar toda la tabla en busca de cantantes objetivo. Si no quieres agregar un índice secundario para que la actualización sea más eficiente, incluye la columna SingerId
en la cláusula WHERE
.
La columna SingerId
es la única columna de clave primaria para el
Tabla Singers
. Para encontrarlo, ejecuta SELECT
en una transacción de solo lectura independiente antes de la transacción de actualización:
SELECT SingerId
FROM Singers
WHERE FirstName = "Marc" AND LastName = "Richards"
-- Recommended: Including a seekable filter in the where clause
UPDATE Singers SET FirstName = "Marcel"
WHERE SingerId = 1;
Evita usar declaraciones DML y mutaciones en la misma transacción
Spanner almacena en búfer las inserciones, actualizaciones y eliminaciones que se realizaron mediante instrucciones DML del lado del servidor, y los resultados son visibles para las instrucciones de SQL y las instrucciones de DML posteriores dentro de la misma transacción. Este comportamiento es diferente a la API de mutación, en la que Spanner almacena en búfer las mutaciones del lado del cliente y envía las del lado del servidor como parte de la operación de confirmación. Como resultado, las mutaciones de la solicitud de confirmación no son visibles para las instrucciones de SQL o declaraciones de DML dentro de la misma transacción.
Evita usar mutaciones y declaraciones DML en la misma transacción. Si usas ambas en la misma transacción, debes tener en cuenta el orden de ejecución en el código de tu biblioteca cliente. Si una transacción contiene DML en la misma solicitud, Spanner ejecuta el Declaraciones DML antes de las mutaciones.
Para las operaciones que solo se admiten con mutaciones, te recomendamos
combinan declaraciones DML y mutaciones en la misma transacción, por ejemplo,
insert_or_update
Si usas ambos, el búfer escribe solo al final de la transacción.
Usa la función PENDING_COMMIT_TIMESTAMP para escribir marcas de tiempo de confirmación
GoogleSQL
Usa la función PENDING_COMMIT_TIMESTAMP
para escribir la marca de tiempo de confirmación en una declaración DML. Spanner selecciona la marca de tiempo de confirmación cuando la transacción
confirmaciones.
PostgreSQL
Usa la función SPANNER.PENDING_COMMIT_TIMESTAMP()
para escribir la marca de tiempo de confirmación en una declaración DML. Spanner selecciona la marca de tiempo de confirmación cuando se confirma la transacción.
DML particionado y funciones de fecha y marca de tiempo
El DML particionado usa una o más transacciones que pueden ejecutarse y confirmarse en momentos diferentes. Si usas las funciones de fecha o marca de tiempo, las filas modificadas pueden contener valores diferentes.
Mejora la latencia con DML por lotes
Para reducir la latencia, usa batch DML para enviar varias declaraciones DML a Spanner en una sola ronda cliente-servidor viaje.
DML por lotes puede aplicar optimizaciones a grupos de declaraciones dentro de por lotes para actualizar los datos de forma más rápida y eficiente.
Ejecuta escrituras con una sola solicitud
Spanner optimiza automáticamente grupos contiguos de operaciones INSERT similares, Las sentencias en lotes UPDATE o DELETE que tienen diferentes valores de parámetro si no violan las dependencias de datos.
Por ejemplo, imagina una situación en la que deseas insertar un gran conjunto de nuevos filas en una tabla llamada
Albums
. Para permitir que Spanner optimice todas las instruccionesINSERT
requeridas en una sola acción eficiente del servidor, primero escribe una instrucción DML adecuada que use parámetros de consulta de SQL:INSERT INTO Albums (SingerId, AlbumId, AlbumTitle) VALUES (@Singer, @Album, @Title);
Luego, envía a Spanner un lote de DML que invoque esta declaración repetidamente y contiguamente, con las repeticiones solo difieren en el que vinculas a los tres parámetros de consulta de la sentencia. Spanner optimiza estos DML estructuralmente idénticos sentencias en una sola operación del servidor antes de ejecutarla.
Ejecuta escrituras en paralelo
Spanner optimiza automáticamente los grupos contiguos de instrucciones DML mediante la ejecución en paralelo cuando hacerlo no incumpla las dependencias de datos. Esta optimización aporta beneficios de rendimiento a un conjunto más amplio de DML por lotes porque se puede aplicar a una combinación de tipos de declaración DML (INSERT, UPDATE y DELETE) y a DML con parámetros o no parametrizado declaraciones.
Por ejemplo, nuestro esquema de muestra tiene las tablas
Singers
,Albums
yAccounts
.Albums
se intercala enSingers
y almacena información sobre los álbumes deSingers
. El siguiente grupo contiguo de instrucciones escribe filas nuevas en varias tablas y no tiene dependencias de datos complejas.INSERT INTO Singers (SingerId, Name) VALUES(1, "John Doe"); INSERT INTO Singers (SingerId, Name) VALUES(2, "Marcel Richards"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (1, 10001, "Album 1"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (1, 10002, "Album 2"); INSERT INTO Albums(SingerId, AlbumId, AlbumTitle) VALUES (2, 10001, "Album 1"); UPDATE Accounts SET Balance = 100 WHERE AccountId = @AccountId;
Spanner optimiza este grupo de declaraciones DML ejecutando de instrucciones en paralelo. Las operaciones de escritura se aplican en el orden de las instrucciones del lote y mantienen la semántica de DML por lotes si una instrucción falla durante la ejecución.