it-swarm-eu.dev

Jaký je nejefektivnější způsob dávkování UPDATE dotazů v MySQL?

Píšu aplikaci, která potřebuje vyprázdnit velké množství aktualizací databáze po delší dobu, a já jsem uvízl v tom, jak optimalizovat dotaz. V současné době používám INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE, který pracuje na dávkování všech hodnot do jednoho dotazu, ale na velkých tabulkách se provádí neuvěřitelně pomalu. Ve skutečnosti nikdy nemusím vkládat řádky.

Další přístupy, které jsem viděl, jsou aktualizace pomocí SET value = CASE WHEN... (což by bylo obtížné vygenerovat kvůli způsobu, jakým vytvářím dotazy, a nejsem si jistý výkonem CASE pro stovky/tisíce klíčů) a jednoduše vícenásobné zřetězené aktualizace. Bylo by jedno z nich rychlejší než moje současná metoda?

Znepokojuje mě, že pokud to dokážu, v MySQL neexistuje žádný idiomatický a účinný způsob. Pokud opravdu neexistuje způsob, který je rychlejší než ON DUPLICATE KEY, stálo by to za to přejít na PostgreSQL a použít jeho UPDATE FROM syntaxe?

Velmi vítáme i další návrhy!

Úpravy: Zde je jedna z tabulek, která se často aktualizuje. Odstranil jsem názvy sloupců, protože jsou irelevantní.

CREATE TABLE IF NOT EXISTS `table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `a` bigint(20) unsigned NOT NULL DEFAULT '0',
  `b` bigint(20) unsigned NOT NULL DEFAULT '0',
  `c` enum('0','1','2') NOT NULL DEFAULT '0',
  `d` char(32) NOT NULL,
  -- trimmed --
  PRIMARY KEY (`id`),
  KEY `a` (`a`),
  KEY `b` (`b`),
  KEY `c` (`c`),
  KEY `d` (`d`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
10
jli

Protože používáte tabulky InnoDB, nejviditelnější optimalizací by bylo seskupení více UPDATEs do transakce.

Když je InnoDB, což je transakční motor, platíte nejen za samotný UPDATE, ale také za všechny transakční režijní náklady: správa vyrovnávací paměti transakcí, protokolu transakcí, spláchnutí protokolu na disk.

Pokud jste s myšlenkou logicky spokojeni, zkuste seskupit 100–1 000 UPDATEs najednou, vždy zalomené takto:

START TRANSACTION;
UPDATE ...
UPDATE ...
UPDATE ...
UPDATE ...
COMMIT;

Možné nevýhody:

  • Jedna chyba sbalí celou transakci (ale bude snadno opravitelná v kódu)
  • Možná budete dlouho čekat, až nahromadíte 1000 UPDATEs, takže můžete také chtít mít nějaký časový limit
  • Složitější kód aplikace.
14
Shlomi Noach