Il Data Manipulation Language partizionato (DML partizionato) è progettato per i seguenti tipi di aggiornamenti ed eliminazioni collettive:
- Pulizia periodica e garbage collection. Alcuni esempi sono l'eliminazione di righe precedenti o
l'impostazione di colonne su
NULL
. - Backfill di nuove colonne con valori predefiniti. Un esempio è l'utilizzo di un'istruzione
UPDATE
per impostare il valore di una nuova colonna suFalse
, dove attualmente èNULL
.
Il DML partizionato non è adatto per l'elaborazione di transazioni su scala ridotta. Se vuoi eseguire un'istruzione su più righe, utilizza DML transazionali con chiavi primarie identificabili. Per ulteriori informazioni, consulta la sezione Utilizzo di DML.
Se devi eseguire il commit di un numero elevato di scritture cieche, ma non hai bisogno di una transazione atomica, puoi apportare modifiche collettive alle tabelle Spanner utilizzando la scrittura batch. Per saperne di più, consulta Modificare i dati utilizzando le scritture in batch.
Puoi ottenere insight sulle query DML partizionate attive e sul loro avanzamento dalle tabelle statistiche nel database Spanner. Per maggiori informazioni, consulta la pagina relativa alle statistiche sulle DML partizionate attive.
DML e DML partizionato
Spanner supporta due modalità di esecuzione per le istruzioni DML:
DML, adatto all'elaborazione delle transazioni. Per maggiori informazioni, consulta la pagina Utilizzo di DML.
DML partizionato, che consente operazioni su larga scala a livello di database con un impatto minimo sull'elaborazione delle transazioni simultanee, partizionando lo spazio delle chiavi ed eseguendo l'istruzione su partizioni in transazioni separate con ambito più ridotto. Per maggiori informazioni, consulta la sezione Utilizzo di DML partizionato.
La tabella seguente evidenzia alcune delle differenze tra le due modalità di esecuzione.
DML | DML partizionato |
---|---|
Le righe che non corrispondono alla clausola WHERE potrebbero essere bloccate. |
Solo le righe che corrispondono alla clausola WHERE vengono bloccate. |
Si applicano limiti per le dimensioni delle transazioni. | Spanner gestisce i limiti delle transazioni e i limiti di contemporaneità per transazione. |
Le dichiarazioni non devono essere idempotenti. | Un'istruzione DML deve essere idempotente per garantire risultati coerenti. |
Una transazione può includere più istruzioni DML e SQL. | Una transazione partizionata può includere una sola istruzione DML. |
Non ci sono limitazioni alla complessità degli estratti conto. | Le istruzioni devono essere completamente partizionabili. |
Puoi creare transazioni di lettura/scrittura nel codice client. | Spanner crea le transazioni. |
Partizionabile e idempotente
Quando viene eseguita un'istruzione DML partizionata, le righe di una partizione non hanno accesso alle righe di altre partizioni e non puoi scegliere il modo in cui Spanner crea le partizioni. Il partizionamento garantisce la scalabilità, ma significa anche che le istruzioni DML partizionate devono essere completamente partizionabili. In altre parole, l'istruzione DML partizionata deve essere esprimibile come unione di un insieme di istruzioni, in cui ogni istruzione accede a una singola riga della tabella e ogni istruzione non accede ad altre tabelle. Ad esempio, un'istruzione DML che accede a più tabelle o esegue un self-join non è partizionabile. Se l'istruzione DML non è partizionabile, Spanner restituisce l'errore BadUsage
.
Queste istruzioni DML sono completamente partizionabili, poiché ogni istruzione può essere applicata a una singola riga della tabella:
UPDATE Singers SET LastName = NULL WHERE LastName = '';
DELETE FROM Albums WHERE MarketingBudget > 10000;
Questa istruzione DML non è completamente partizionabile, perché accede a più tabelle:
# Not fully partitionable
DELETE FROM Singers WHERE
SingerId NOT IN (SELECT SingerId FROM Concerts);
Spanner potrebbe eseguire più volte un'istruzione DML partizionata su alcune partizioni a causa di nuovi tentativi a livello di rete. Di conseguenza, un'istruzione potrebbe essere eseguita più di una volta su una riga. L'istruzione deve quindi essere idempotente per produrre risultati coerenti. Un'istruzione è idempotente se la esegui più volte su una singola riga porta allo stesso risultato.
Questa istruzione DML è idempotente:
UPDATE Singers SET MarketingBudget = 1000 WHERE true;
Questa istruzione DML non è idempotente:
UPDATE Singers SET MarketingBudget = 1.5 * MarketingBudget WHERE true;
Blocco delle righe
Spanner acquisisce un blocco solo se una riga è candidata per l'aggiornamento o
l'eliminazione. Questo comportamento è diverso
dall'esecuzione di DML, che potrebbe bloccare
righe con blocco di lettura che non corrispondono alla clausola WHERE
.
Esecuzione e transazioni
La partizionamento di un'istruzione DML o meno dipende dal metodo della libreria client scelto per l'esecuzione. Ogni libreria client fornisce metodi separati per l'esecuzione di DML e l'esecuzione di DML partizionata.
Puoi eseguire una sola istruzione DML partizionata in una chiamata al metodo della libreria client.
Spanner non applica le istruzioni DML partizionate atomicamente all'intera tabella. Spanner, tuttavia, applica istruzioni DML partizionate atomicamente su ogni partizione.
Il DML partizionato non supporta il commit o il rollback. Spanner esegue e applica immediatamente l'istruzione DML.
- Se annulli l'operazione, Spanner annulla le partizioni in esecuzione e non avvia quelle rimanenti. Spanner non esegue il rollback delle partizioni già eseguite.
- Se l'esecuzione dell'istruzione causa un errore, l'esecuzione si interrompe su tutte le partizioni e Spanner restituisce l'errore per l'intera operazione. Alcuni esempi di errori sono violazioni dei vincoli dei tipi di dati, violazioni di
UNIQUE INDEX
e violazioni diON DELETE NO ACTION
. A seconda del momento in cui l'esecuzione non è riuscita, l'istruzione potrebbe essere stata eseguita correttamente su alcune partizioni e non essere mai stata eseguita su altre partizioni.
Se l'istruzione DML partizionata ha esito positivo, Spanner ha eseguito l'istruzione almeno una volta su ogni partizione dell'intervallo di chiavi.
Conteggio delle righe modificate
Un'istruzione DML partizionata restituisce un limite inferiore al numero di righe modificate. Potrebbe non essere un conteggio esatto del numero di righe modificate, perché non vi è alcuna garanzia che Spanner conteggi tutte le righe modificate.
Limiti transazioni
Spanner crea le partizioni e le transazioni necessarie per eseguire un'istruzione DML partizionata. Si applicano limiti alle transazioni o limiti di contemporaneità per transazione, ma Spanner tenta di mantenere le transazioni entro i limiti.
Spanner consente un massimo di 20.000 istruzioni DML concomitanti e partizionate per database.
Funzionalità non supportate
Spanner non supporta alcune funzionalità per il DML partizionato:
INSERT
non supportato.- Console Google Cloud: non puoi eseguire istruzioni DML partizionate nella console Google Cloud.
- Piani di query e profilazione: Google Cloud CLI e le librerie client non supportano i piani di query e la profilazione.
- Sottoquery che leggono da un'altra tabella o da un'altra riga della stessa tabella.
Per scenari complessi, come lo spostamento di una tabella o trasformazioni che richiedono join tra tabelle, valuta la possibilità di utilizzare il connettore Dataflow.
Esempi
Il seguente esempio di codice aggiorna la colonna MarketingBudget
della tabella Albums
.
C++
Puoi utilizzare la funzione ExecutePartitionedDml()
per eseguire un'istruzione DML partizionata.
C#
Utilizzi il metodo ExecutePartitionedUpdateAsync()
per eseguire un'istruzione DML partizionata.
Go
Utilizzi il metodo PartitionedUpdate()
per eseguire un'istruzione DML partizionata.
Java
Utilizzi il metodo executePartitionedUpdate()
per eseguire un'istruzione DML partizionata.
Node.js
Utilizzi il metodo runPartitionedUpdate()
per eseguire un'istruzione DML partizionata.
PHP
Utilizzi il metodo executePartitionedUpdate()
per eseguire un'istruzione DML partizionata.
Python
Utilizzi il metodo execute_partitioned_dml()
per eseguire un'istruzione DML partizionata.
Ruby
Utilizzi il metodo execute_partitioned_update()
per eseguire un'istruzione DML partizionata.
Il seguente esempio di codice elimina le righe dalla tabella Singers
in base alla colonna SingerId
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Che cosa succede dopo?
Scopri come modificare i dati utilizzando DML.
Scopri di più sulle best practice per Data Manipulation Language (DML).
Per scoprire le differenze tra DML e mutazioni, consulta Confronto tra DML e Mutazioni
Valuta la possibilità di utilizzare il connettore Dataflow per altri scenari di trasformazione dei dati.