Mysql
 sql >> Database >  >> RDS >> Mysql

L'aggiornamento in blocco di Sqlalchemy in MySQL funziona molto lentamente

Puoi accelerare le operazioni di aggiornamento in blocco con un trucco, anche se il server del database (come nel tuo caso) ha una latenza molto scarsa. Invece di aggiornare direttamente la tua tabella, usi una tabella di stage per inserire i tuoi nuovi dati molto velocemente, quindi esegui un aggiornamento unisciti alla tabella di destinazione . Questo ha anche il vantaggio di ridurre notevolmente il numero di istruzioni da inviare al database.

Come funziona con gli AGGIORNAMENTI?

Supponi di avere una tabella entries e hai sempre nuovi dati in arrivo, ma vuoi solo aggiornare quelli che sono già stati memorizzati. Crei una copia della tua tabella di destinazione entries_stage con solo i campi pertinenti:

entries = Table('entries', metadata,
    Column('id', Integer, autoincrement=True, primary_key=True),
    Column('value', Unicode(64), nullable=False),
)

entries_stage = Table('entries_stage', metadata,
    Column('id', Integer, autoincrement=False, unique=True),
    Column('value', Unicode(64), nullable=False),
)

Quindi inserisci i tuoi dati con un inserimento in blocco. Questo può essere ulteriormente accelerato se si utilizza la sintassi di inserimento multivalore di MySQL, che non è supportata nativamente da SQLAlchemy, ma può essere compilata senza troppe difficoltà.

INSERT INTO enries_stage (`id`, `value`)
VALUES
(1, 'string1'), (2, 'string2'), (3, 'string3'), ...;

Alla fine, aggiorni i valori della tabella di destinazione con i valori della tabella di fase in questo modo:

 UPDATE entries e
 JOIN entries_stage es ON e.id = es.id
 SET e.value = es.value;

Allora hai finito.

E gli inserti?

Questo funziona anche per velocizzare gli inserti ovviamente. Poiché hai già i dati nella tabella di stage , tutto ciò che devi fare è emettere un INSERT INTO ... SELECT istruzione, con i dati che non sono in destination-table ancora.

INSERT INTO entries (id, value)
SELECT FROM entries_stage es
LEFT JOIN entries e ON e.id = es.id
HAVING e.id IS NULL;

La cosa bella è che non devi fare INSERT IGNORE , REPLACE o ON DUPLICATE KEY UPDATE , che incrementerà la tua chiave primaria, anche se non faranno nulla .