sql >> Database >  >> RDS >> Mysql

Sqlalchemy bulk-update in MySQL werkt erg traag

U kunt met een truc bulk-updatebewerkingen versnellen, zelfs als de databaseserver (zoals in uw geval) een zeer slechte latentie heeft. In plaats van je tabel direct bij te werken, gebruik je een stage-table om uw nieuwe gegevens heel snel in te voeren, voer dan één join-update uit naar de bestemmingstabel . Dit heeft ook als voordeel dat je het aantal verklaringen dat je naar de database moet sturen behoorlijk drastisch vermindert.

Hoe werkt dit met UPDATE's?

Stel dat je een tabel hebt entries en er komen voortdurend nieuwe gegevens binnen, maar u wilt alleen de gegevens bijwerken die al zijn opgeslagen. U maakt een kopie van uw bestemmingstabel entries_stage met alleen de relevante velden erin:

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),
)

Vervolgens vul je je gegevens in met een bulk-insert. Dit kan nog verder worden versneld als u MySQL's syntaxis voor het invoegen van meerdere waarden gebruikt, die niet standaard wordt ondersteund door SQLAlchemy, maar zonder veel moeite kan worden gebouwd.

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

Uiteindelijk werk je de waarden van de bestemmingstabel bij met de waarden uit de stage-tabel als volgt:

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

Dan ben je klaar.

Hoe zit het met inlegvellen?

Dit werkt natuurlijk ook om het invoegen te versnellen. Aangezien je de gegevens al in de stage-table hebt staan , het enige wat u hoeft te doen is een INSERT INTO ... SELECT verklaring, met de gegevens die niet in bestemmingstabel nog niet.

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

Het leuke hiervan is dat je niet hoeft te doen INSERT IGNORE , REPLACE of ON DUPLICATE KEY UPDATE , die uw primaire sleutel zal verhogen, zelfs als ze niets zullen doen .




  1. Ruby on rails verbindingsprobleem

  2. Rethink Flask - Een eenvoudige takenlijst mogelijk gemaakt door Flask en RethinkDB

  3. Hoe JSONB in ​​Postgresql invoegen met Python?

  4. Best practice voor het opslaan van gebruikersnamen en wachtwoorden in MySQL-databases