Du kan påskynda massuppdateringsoperationer med ett knep, även om databasservern (som i ditt fall) har en mycket dålig latens. Istället för att uppdatera din tabell direkt använder du en stage-table för att infoga dina nya data mycket snabbt, gör sedan en uppdatering till destinationstabellen . Detta har också fördelen att du minskar antalet påståenden du måste skicka till databasen ganska dramatiskt.
Hur fungerar det här med UPPDATERINGAR?
Säg att du har en tabell entries
och du har nya data som kommer in hela tiden, men du vill bara uppdatera de som redan har lagrats. Du skapar en kopia av din destinationstabell entries_stage
med endast de relevanta fälten i:
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),
)
Sedan infogar du dina data med en bulkinsert. Detta kan påskyndas ytterligare om du använder MySQL:s multipla value insert-syntax, som inte stöds av SQLAlchemy, men som kan byggas utan större svårighet.
INSERT INTO enries_stage (`id`, `value`)
VALUES
(1, 'string1'), (2, 'string2'), (3, 'string3'), ...;
I slutändan uppdaterar du värdena för destinationstabellen med värdena från stegtabellen så här:
UPDATE entries e
JOIN entries_stage es ON e.id = es.id
SET e.value = es.value;
Då är du klar.
Vad sägs om inlägg?
Detta fungerar naturligtvis också för att snabba upp skären. Eftersom du redan har data i stage-tabellen , allt du behöver göra är att utfärda en INSERT INTO ... SELECT
uttalande, med data som inte finns i destinationstabell ännu.
INSERT INTO entries (id, value)
SELECT FROM entries_stage es
LEFT JOIN entries e ON e.id = es.id
HAVING e.id IS NULL;
Det fina med detta är att du inte behöver göra INSERT IGNORE
, REPLACE
eller ON DUPLICATE KEY UPDATE
, som kommer att öka din primära nyckel, även om de inte gör någonting .