Du kan fremskynde masseopdateringsoperationer med et trick, selvom databaseserveren (som i dit tilfælde) har en meget dårlig latenstid. I stedet for at opdatere din tabel direkte, bruger du en stage-tabel for at indsætte dine nye data meget hurtigt, så lav en opdatering til destinationstabellen . Dette har også den fordel, at du reducerer antallet af opgørelser, du skal sende til databasen, ganske dramatisk.
Hvordan fungerer dette med OPDATERINGER?
Lad os sige, at du har en tabel entries
og du har hele tiden nye data, men du vil kun opdatere dem, der allerede er gemt. Du opretter en kopi af din destinationstabel entries_stage
med kun de relevante felter 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),
)
Derefter indsætter du dine data med en bulk-indsats. Dette kan fremskyndes endnu mere, hvis du bruger MySQL's multiple value insert-syntaks, som ikke er indbygget understøttet af SQLAlchemy, men kan bygges uden større besvær.
INSERT INTO enries_stage (`id`, `value`)
VALUES
(1, 'string1'), (2, 'string2'), (3, 'string3'), ...;
Til sidst opdaterer du værdierne for destinationstabellen med værdierne fra fasetabellen sådan her:
UPDATE entries e
JOIN entries_stage es ON e.id = es.id
SET e.value = es.value;
Så er du færdig.
Hvad med indsatser?
Dette virker selvfølgelig også for at fremskynde indsatser. Da du allerede har dataene i stage-tabellen , alt hvad du skal gøre er at udstede en INSERT INTO ... SELECT
sætning, med de data, der ikke er i destinationstabel endnu.
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 gode ved dette er, at du ikke behøver at gøre INSERT IGNORE
, REPLACE
eller ON DUPLICATE KEY UPDATE
, som forøger din primære nøgle, selvom de ikke gør noget .