MySQL блокирует таблицу для записи при добавлении нового столбца со значением по умолчанию - PullRequest
0 голосов
/ 23 мая 2019

Если я выполню ниже sql, будет ли mysql блокировать полную таблицу (запись не может быть выполнена до завершения операции ниже)?на мой взгляд, да, так как он должен изменить все строки и добавить значения по умолчанию.Однако эта операция заняла всего 4 секунды на таблице с 1 миллионом строк.

ALTER TABLE `user` ADD COLUMN `col1` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1;

Однако, когда я попытался разбить операцию на 2 отдельных запроса (пытаясь сократить время блокировки таблицы из-за моего неполного понимания), второй запрос выполнялся более 100 секунд

ALTER TABLE `user` ADD COLUMN `col1` TINYINT(1) UNSIGNED; // happens instantly
UPDATE user set col1 = true ; // takes > 100 seconds

Итак, я хотел знать, почему такая большая разница во времени выполнения, когда конечный результат одинаков.

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Нашел ответ по https://mysqlserverteam.com/mysql-8-0-innodb-now-supports-instant-add-column/ с помощью алгоритма INSTANT innoDB просто добавляет новый столбец в метаданные таблицы вместе со значением по умолчанию. Отдельные строки не изменяются, что экономит время в первом запросе, о котором я говорил. Во время операции чтения используется значение по умолчанию из метаданных таблицы, любая операция записи восстанавливает строку и добавляет вновь добавленный столбец в саму строку. Это разбиение одной операции ALTER на 2 было медленным, поскольку последняя изменяла каждую отдельную строку

0 голосов
/ 23 мая 2019

Не могу точно сказать, но вот мое предположение (для движка InnoDB и формата строк DYNAMIC / COMPACT):

Как хранится NULL? Вот что говорит документация :

Часть переменной длины заголовка записи содержит битовый вектор для указания NULL столбцов. Если количество столбцов в индексе это может быть NULL равно <strong><em>N</em></strong>, битовый вектор занимает CEILING(<strong><em>N</em></strong>/8) байт. (Например, если есть где-то от 9 до 16 столбцов, которые могут быть NULL, битовый вектор использует два байта.) Столбцы NULL не занимают места, кроме немного в этом векторе. [...]

Если у вас уже есть (скажем) три обнуляемых столбца, то пять битов в упомянутом битовом векторе не используются. Мы можем предположить, что они предустановлены для представления значений NULL (это имело бы смысл). Теперь, когда вы добавляете обнуляемый столбец с DEAFAULT NULL (который является настройкой по умолчанию для обнуляемых столбцов), тогда никакие данные не нужно изменять в таблице - только метаданные таблицы. Это объясняет, почему операция ALTER является «мгновенной».

Вторая часть (инструкция UPDATE) будет не только изменять содержимое каждой строки в таблице, но также и их размер. Это означает, что двигатель должен найти новое место для каждого ряда. Если вы когда-либо наблюдали за процессом дефрагментации, вы могли бы знать, что часто было бы намного быстрее просто переписать все данные.

...