Я пишу приложение, которое должно сбрасывать большое количество обновлений в базу данных в течение длительного периода времени, и я застрял в том, как оптимизировать запрос. В настоящее время я использую INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE
, который работает, чтобы объединить все значения в один запрос, но выполняется мучительно медленно на больших таблицах. Мне никогда не нужно вставлять строки.
Другие подходы, которые я видел, - это обновление с использованием SET value = CASE WHEN...
(которое было бы трудно генерировать из-за способа, которым я строю запросы, и я не уверен в производительности CASE
для сотен / тысяч ключей), и просто несколько сцепленных обновления. Будет ли один из них быстрее, чем мой текущий метод?
Меня сбивает с толку, что, насколько я могу судить, в MySQL нет идиоматического и эффективного способа сделать это. Если нет более быстрого способа, ON DUPLICATE KEY
стоит ли переходить на PostgreSQL и использовать его UPDATE FROM
синтаксис?
Любые другие предложения также приветствуются!
Изменить: вот одна из таблиц, которая часто обновляется. Я удалил имена столбцов, потому что они не имеют значения.
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;
Ответы:
Поскольку вы используете
InnoDB
таблицы, наиболее очевидной оптимизацией будет группирование несколькихUPDATE
элементов в транзакцию.С
InnoDB
, будучи транзакционный двигатель, вы платите не только заUPDATE
себя, но и для всех транзакционных накладных расходов: управление буфером транзакций, журнал транзакций, промывка журнала на диск.Если вы логически согласны с этой идеей, попробуйте сгруппировать 100-1000
UPDATE
с за раз, каждый раз оборачивая так:Возможные недостатки:
UPDATE
с, поэтому вам также может потребоваться некоторое время ожидания.источник