Bulk update в MySQL

Ревизия #2

В порыве пятничного отлынивания от работы, совместно с коллегой, родили нечто.

Нечто позволяет одним запросом обновлять неограниченное количество записей. Причем разные столбцы, на разные данные, в зависимости от уникального ключа.

Нечто имеет следующие недостатки:

  • требует уникального ключа
  • если строки с подходящим ключом нет, то она добавится
  • для построения требует знаний о типах полей таблицы
  • мускл на него ругается ворнингами
  • NULL таким образом вставить невозможно

SQL:

CREATE TABLE  `bulk_update` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `int` int(11) NOT NULL DEFAULT '7',
  `str` varchar(5) NOT NULL DEFAULT 'def',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

INSERT INTO `bulk_update` (`id`, `int`, `str`)
  VALUES (1, 1, 'a'), (2, 2, 'b'), (3, 3, 'c');

INSERT INTO `bulk_update` (`id`, `int`, `str`)
  VALUES (1, 22, null), (2, null, 'bb')
  ON DUPLICATE KEY UPDATE
    `int` = IFNULL(NULLIF(VALUES(`int`), 0), `int`),
    `str` = IFNULL(NULLIF(VALUES(`str`), ''), `str`);

SELECT * FROM bulk_update;
+----+-----+-----+
| id |   int | str |
+----+-----+-----+
|  1 |   22 | a   |
|  2 |   2  | bb  |
|  3 |   3  | c   |
+----+-----+-----+

Тесты скорости показали следующие результаты:

Обновляемых записей По одному (qps) Кучкой (qps)
10 2296 3620
100 3480 11097
1000 3959 18804

Во время теста параллельно пускались три скрипта, делающие разнообразные селекты к таблице.

Тест, как всегда, прилагается.

В общем штука получилась интересная, но какая-то костылеподобная.

UPD: Теперь работает и для столбцов с NOT NULL и без оного.

Оставить комментарий